整合營銷服務(wù)商

          電腦端+手機端+微信端=數(shù)據(jù)同步管理

          免費咨詢熱線:

          還在用Zipkin分布式服務(wù)鏈路追蹤?來試試這個吧

          SpringCloud問世以來,微服務(wù)以席卷之勢風(fēng)靡全球,企業(yè)架構(gòu)都在從傳統(tǒng)SOA向微服務(wù)轉(zhuǎn)型。然而微服務(wù)這把雙刃劍在帶來各種優(yōu)勢的同時,也給運維、性能監(jiān)控、錯誤的排查帶來的極大的困難。

          在大型項目中,服務(wù)架構(gòu)會包含數(shù)十乃至上百個服務(wù)節(jié)點。往往一次請求會設(shè)計到多個微服務(wù),想要排查一次請求鏈路中經(jīng)過了哪些節(jié)點,每個節(jié)點的執(zhí)行情況如何,就成為了亟待解決的問題。于是分布式系統(tǒng)的APM管理系統(tǒng)應(yīng)運而生。

          什么是APM系統(tǒng)?

          APM系統(tǒng)可以幫助理解系統(tǒng)行為、用于分析性能問題的工具,以便發(fā)生故障的時候,能夠快速定位和解決問題,這就是APM系統(tǒng),全稱是(Application Performance Monitor)。

          谷歌公開的論文提到的Google Dapper可以說是最早的APM系統(tǒng)了,給google的開發(fā)者和運維團隊幫了大忙,所以谷歌公開論文分享了Dapper。

          而后,很多的技術(shù)公司基于這篇論文的原理,設(shè)計開發(fā)了很多出色的APM框架,例如Pinpoint、SkyWalking等。

          而SpringCloud官網(wǎng)也集成了一套這樣的系統(tǒng):Spring Cloud Sleuth,結(jié)合Zipkin。

          APM的基本原理

          目前大部分的APM系統(tǒng)都是基于Google的Dapper原理實現(xiàn),我們簡單來看看Dapper中的概念和實現(xiàn)原理。

          先來看一次請求調(diào)用示例:

          1. 服務(wù)集群中包括:前端(A),兩個中間層(B和C),以及兩個后端(D和E)
          2. 當用戶發(fā)起一個請求時,首先到達前端A服務(wù),然后A分別對B服務(wù)和C服務(wù)進行RPC調(diào)用;
          3. B服務(wù)處理完給A做出響應(yīng),但是C服務(wù)還需要和后端的D服務(wù)和E服務(wù)交互之后再返還給A服務(wù),最后由A服務(wù)來響應(yīng)用戶的請求;

          如何才能實現(xiàn)跟蹤呢?

          Google的Dapper設(shè)計了下面的幾個概念用來記錄請求鏈路:

          Span:請求中的基本工作單元,每一次鏈路調(diào)用(RPC、Rest、數(shù)據(jù)庫調(diào)用)都會創(chuàng)建一個Span。大概結(jié)構(gòu)如下:
          type Span struct {
           TraceID int64 // 用于標示一次完整的請求id
           Name string // 單元名稱
           ID int64 // 當前這次調(diào)用span_id
           ParentID int64 // 上層服務(wù)的span_id,最上層服務(wù)parent_id為null,代表根服務(wù)
           Annotation []Annotation // 注釋,用于記錄調(diào)用中的詳細信息,例如時間
          }
          • Trace:一次完整的調(diào)用鏈路,包含多個Span的樹狀結(jié)構(gòu),具有唯一的TraceID

          一次請求的每個鏈路,通過spanId、parentId就能串聯(lián)起來:

          當然,從請求到服務(wù)器開始,服務(wù)器返回response結(jié)束,每個span存在相同的唯一標識trace_id。

          APM的篩選標準

          目前主流的APM框架都會包含下列幾個組件來完成鏈路信息的收集和展示:

          • 探針(Agent):負責(zé)在客戶端程序運行時搜索服務(wù)調(diào)用鏈路信息,發(fā)送給收集器
          • 收集器(Collector):負責(zé)將數(shù)據(jù)格式化,保存到存儲器
          • 存儲器(Storage):保存數(shù)據(jù)
          • UI界面(WebUI):統(tǒng)計并展示收集到的信息

          因此,要篩選一款合格的APM框架,就是對比各個組件的使用差異,主要對比項:

          • 探針的性能

          主要是agent對服務(wù)的吞吐量、CPU和內(nèi)存的影響。如果探針在收集微服務(wù)運行數(shù)據(jù)時,對微服務(wù)的運行產(chǎn)生了比較大的性能影響,相信沒什么人愿意使用。

          • collector的可擴展性

          能夠水平擴展以便支持大規(guī)模服務(wù)器集群,保證收集器的高可用特性。

          • 全面的調(diào)用鏈路數(shù)據(jù)分析

          數(shù)據(jù)的分析要 ,分析的維度盡可能。跟蹤系統(tǒng)能提供足夠快的信息反饋,就可以對生產(chǎn)環(huán)境下的異常狀況做出快速反應(yīng),最好提供代碼級別的可見性以便輕松定位失敗點和瓶頸。

          • 對于開發(fā)透明,容易開關(guān)

          即也作為業(yè)務(wù)組件,應(yīng)當盡可能少入侵或者無入侵其他業(yè)務(wù)系統(tǒng),對于使用方透明,減少開發(fā)人員的負擔(dān)。

          • 完整的調(diào)用鏈應(yīng)用拓撲

          自動檢測應(yīng)用拓撲,幫助你搞清楚應(yīng)用的架構(gòu)

          接下來,我們就對比下目前比較常見的三種APM框架的各項指標,分別是:

          • ZIPkin:由Twitter公司開源,開放源代碼分布式的跟蹤系統(tǒng),用于收集服務(wù)的定時數(shù)據(jù),以解決微服務(wù)架構(gòu)中的延遲問題,包括:數(shù)據(jù)的收集、存儲、查找和展現(xiàn)。
          • Pinpoint:一款對Java編寫的大規(guī)模分布式系統(tǒng)的APM工具,由韓國人開源的分布式跟蹤組件。
          • Skywalking:國產(chǎn)的優(yōu)秀APM組件,是一個對JAVA分布式應(yīng)用程序集群的業(yè)務(wù)運行情況進行追蹤、告警和分析的系統(tǒng)?,F(xiàn)在是Apache的頂級項目之一

          三者對比如下:

          可見,zipkin的探針性能、開發(fā)透明性、數(shù)據(jù)分析能力都不占優(yōu),實在是下下之選。

          而pinpoint在數(shù)據(jù)分析能力、開發(fā)透明性上有較大的優(yōu)勢,不過Pinpoint的部署相對比較復(fù)雜,需要的硬件資源較高。

          Skywalking的探針性能和開發(fā)透明性上具有較大優(yōu)勢,數(shù)據(jù)分析能力上也還不錯,重要的是其部署比較方便靈活,比起Pinpoint更適合中小型企業(yè)使用。

          因此,本文會帶著大家學(xué)習(xí)Skywalking的使用。

          Skywalking介紹

          SkyWalking 創(chuàng)建于2015年,提供分布式追蹤功能。從5.x開始,項目進化為一個完成功能的Application Performance Management系統(tǒng)。 他被用于追蹤、監(jiān)控和診斷分布式系統(tǒng),特別是使用微服務(wù)架構(gòu),云原生或容積技術(shù)。提供以下主要功能:

          • 分布式追蹤和上下文傳輸
          • 應(yīng)用、實例、服務(wù)性能指標分析
          • 根源分析
          • 應(yīng)用拓撲分析
          • 應(yīng)用和服務(wù)依賴分析
          • 慢服務(wù)檢測
          • 性能優(yōu)化

          主要的特征:

          • 多語言探針或類庫
            • Java自動探針,追蹤和監(jiān)控程序時,不需要修改源碼。
            • 社區(qū)提供的其他多語言探針
              • .NET Core
              • Node.js
          • 多種后端存儲: ElasticSearch, H2
          • 支持
            OpenTracing
            • Java自動探針支持和OpenTracing API協(xié)同工作
          • 輕量級、完善功能的后端聚合和分析
          • 現(xiàn)代化Web UI
          • 日志集成
          • 應(yīng)用、實例和服務(wù)的告警

          Skywalking的安裝

          先來看下Skywalking的官方給出的結(jié)構(gòu)圖:

          大致分四個部分:

          • skywalking-oap-server:就是Observability Analysis Platformd的服務(wù),用來收集和處理探針發(fā)來的數(shù)據(jù)
          • skywalking-UI:就是skywalking提供的Web UI 服務(wù),圖形化方式展示服務(wù)鏈路、拓撲圖、trace、性能監(jiān)控等
          • agent:探針,獲取服務(wù)調(diào)用的鏈路信息、性能信息,發(fā)送到skywalking的OAP服務(wù)
          • Storage:存儲,一般選擇elasticsearch

          Skywalking支持windows或者Linux環(huán)境部署。這里我們選擇在Linux下安裝Skywalking,大家要先確保自己的Linux環(huán)境中有elasticsearch在啟動中。

          接下來的安裝分為三步:

          • 下載安裝包
          • 安裝Skywalking的OAP服務(wù)和WebUI
          • 在服務(wù)中部署探針

          下載安裝包

          安裝包可以在Skywalking的官網(wǎng)下載,

          目前最新版本是8.0.1版本:

          下載好的安裝包:

          安裝OAP服務(wù)和WebUI

          安裝

          將下載好的安裝包解壓到Linux的某個目錄下:

          tar xvf apache-skywalking-apm-es7-8.0.1.tar.gz

          然后對解壓好的文件夾重命名:

          mv apache-skywalking-apm-es7 skywalking

          進入解壓好的目錄:

          cd skywalking

          查看目錄結(jié)構(gòu):

          幾個關(guān)鍵的目錄:

          • agent:探針
          • bin:啟動腳本
          • config:配置文件
          • logs:日志
          • oap-libs:依賴
          • webapp:WebUI

          這里要修改config目錄中的application.yml文件,詳細配置見官網(wǎng)。

          配置

          進入config目錄,修改application.yml,主要是把存儲方案從h2改為elasticsearch

          可以直接使用下面的配置:

          cluster:
            selector: ${SW_CLUSTER:standalone}
            standalone:
          core:
            selector: ${SW_CORE:default}
            default:
              role: ${SW_CORE_ROLE:Mixed} # Mixed/Receiver/Aggregator
              restHost: ${SW_CORE_REST_HOST:0.0.0.0}
              restPort: ${SW_CORE_REST_PORT:12800}
              restContextPath: ${SW_CORE_REST_CONTEXT_PATH:/}
              gRPCHost: ${SW_CORE_GRPC_HOST:0.0.0.0}
              gRPCPort: ${SW_CORE_GRPC_PORT:11800}
              gRPCSslEnabled: ${SW_CORE_GRPC_SSL_ENABLED:false}
              gRPCSslKeyPath: ${SW_CORE_GRPC_SSL_KEY_PATH:""}
              gRPCSslCertChainPath: ${SW_CORE_GRPC_SSL_CERT_CHAIN_PATH:""}
              gRPCSslTrustedCAPath: ${SW_CORE_GRPC_SSL_TRUSTED_CA_PATH:""}
              downsampling:
                - Hour
                - Day
                - Month
              # Set a timeout on metrics data. After the timeout has expired, the metrics data will automatically be deleted.
              enableDataKeeperExecutor: ${SW_CORE_ENABLE_DATA_KEEPER_EXECUTOR:true} # Turn it off then automatically metrics data delete will be close.
              dataKeeperExecutePeriod: ${SW_CORE_DATA_KEEPER_EXECUTE_PERIOD:5} # How often the data keeper executor runs periodically, unit is minute
              recordDataTTL: ${SW_CORE_RECORD_DATA_TTL:3} # Unit is day
              metricsDataTTL: ${SW_CORE_RECORD_DATA_TTL:7} # Unit is day
              # Cache metric data for 1 minute to reduce database queries, and if the OAP cluster changes within that minute,
              # the metrics may not be accurate within that minute.
              enableDatabaseSession: ${SW_CORE_ENABLE_DATABASE_SESSION:true}
              topNReportPeriod: ${SW_CORE_TOPN_REPORT_PERIOD:10} # top_n record worker report cycle, unit is minute
              # Extra model column are the column defined by in the codes, These columns of model are not required logically in aggregation or further query,
              # and it will cause more load for memory, network of OAP and storage.
              # But, being activated, user could see the name in the storage entities, which make users easier to use 3rd party tool, such as Kibana->ES, to query the data by themselves.
              activeExtraModelColumns: ${SW_CORE_ACTIVE_EXTRA_MODEL_COLUMNS:false}
              # The max length of service + instance names should be less than 200
              serviceNameMaxLength: ${SW_SERVICE_NAME_MAX_LENGTH:70}
              instanceNameMaxLength: ${SW_INSTANCE_NAME_MAX_LENGTH:70}
              # The max length of service + endpoint names should be less than 240
              endpointNameMaxLength: ${SW_ENDPOINT_NAME_MAX_LENGTH:150}
          storage:
            selector: ${SW_STORAGE:elasticsearch7}
            elasticsearch7:
              nameSpace: ${SW_NAMESPACE:""}
              clusterNodes: ${SW_STORAGE_ES_CLUSTER_NODES:localhost:9200}
              protocol: ${SW_STORAGE_ES_HTTP_PROTOCOL:"http"}
              trustStorePath: ${SW_STORAGE_ES_SSL_JKS_PATH:""}
              trustStorePass: ${SW_STORAGE_ES_SSL_JKS_PASS:""}
              dayStep: ${SW_STORAGE_DAY_STEP:1} # Represent the number of days in the one minute/hour/day index.
              user: ${SW_ES_USER:""}
              password: ${SW_ES_PASSWORD:""}
              secretsManagementFile: ${SW_ES_SECRETS_MANAGEMENT_FILE:""} # Secrets management file in the properties format includes the username, password, which are managed by 3rd party tool.
              indexShardsNumber: ${SW_STORAGE_ES_INDEX_SHARDS_NUMBER:1} # The index shards number is for store metrics data rather than basic segment record
              superDatasetIndexShardsFactor: ${SW_STORAGE_ES_SUPER_DATASET_INDEX_SHARDS_FACTOR:5} # Super data set has been defined in the codes, such as trace segments. This factor provides more shards for the super data set, shards number = indexShardsNumber * superDatasetIndexShardsFactor. Also, this factor effects Zipkin and Jaeger traces.
              indexReplicasNumber: ${SW_STORAGE_ES_INDEX_REPLICAS_NUMBER:0}
              # Batch process setting, refer to https://www.elastic.co/guide/en/elasticsearch/client/java-api/5.5/java-docs-bulk-processor.html
              bulkActions: ${SW_STORAGE_ES_BULK_ACTIONS:1000} # Execute the bulk every 1000 requests
              flushInterval: ${SW_STORAGE_ES_FLUSH_INTERVAL:10} # flush the bulk every 10 seconds whatever the number of requests
              concurrentRequests: ${SW_STORAGE_ES_CONCURRENT_REQUESTS:2} # the number of concurrent requests
              resultWindowMaxSize: ${SW_STORAGE_ES_QUERY_MAX_WINDOW_SIZE:10000}
              metadataQueryMaxSize: ${SW_STORAGE_ES_QUERY_MAX_SIZE:5000}
              segmentQueryMaxSize: ${SW_STORAGE_ES_QUERY_SEGMENT_SIZE:200}
              profileTaskQueryMaxSize: ${SW_STORAGE_ES_QUERY_PROFILE_TASK_SIZE:200}
              advanced: ${SW_STORAGE_ES_ADVANCED:""}
            h2:
              driver: ${SW_STORAGE_H2_DRIVER:org.h2.jdbcx.JdbcDataSource}
              url: ${SW_STORAGE_H2_URL:jdbc:h2:mem:skywalking-oap-db}
              user: ${SW_STORAGE_H2_USER:sa}
              metadataQueryMaxSize: ${SW_STORAGE_H2_QUERY_MAX_SIZE:5000}
          receiver-sharing-server:
            selector: ${SW_RECEIVER_SHARING_SERVER:default}
            default:
              authentication: ${SW_AUTHENTICATION:""}
          receiver-register:
            selector: ${SW_RECEIVER_REGISTER:default}
            default:
          
          receiver-trace:
            selector: ${SW_RECEIVER_TRACE:default}
            default:
              sampleRate: ${SW_TRACE_SAMPLE_RATE:10000} # The sample rate precision is 1/10000. 10000 means 100% sample in default.
              slowDBAccessThreshold: ${SW_SLOW_DB_THRESHOLD:default:200,mongodb:100} # The slow database access thresholds. Unit ms.
          ?
          receiver-jvm:
            selector: ${SW_RECEIVER_JVM:default}
            default:
          ?
          receiver-clr:
            selector: ${SW_RECEIVER_CLR:default}
            default:
          ?
          receiver-profile:
            selector: ${SW_RECEIVER_PROFILE:default}
            default:
          ?
          service-mesh:
            selector: ${SW_SERVICE_MESH:default}
            default:
          ?
          istio-telemetry:
            selector: ${SW_ISTIO_TELEMETRY:default}
            default:
          ?
          envoy-metric:
            selector: ${SW_ENVOY_METRIC:default}
            default:
              acceptMetricsService: ${SW_ENVOY_METRIC_SERVICE:true}
              alsHTTPAnalysis: ${SW_ENVOY_METRIC_ALS_HTTP_ANALYSIS:""}
          ?
          prometheus-fetcher:
            selector: ${SW_PROMETHEUS_FETCHER:default}
            default:
              active: ${SW_PROMETHEUS_FETCHER_ACTIVE:false}
          ?
          receiver_zipkin:
            selector: ${SW_RECEIVER_ZIPKIN:-}
            default:
              host: ${SW_RECEIVER_ZIPKIN_HOST:0.0.0.0}
              port: ${SW_RECEIVER_ZIPKIN_PORT:9411}
              contextPath: ${SW_RECEIVER_ZIPKIN_CONTEXT_PATH:/}
          ?
          receiver_jaeger:
            selector: ${SW_RECEIVER_JAEGER:-}
            default:
              gRPCHost: ${SW_RECEIVER_JAEGER_HOST:0.0.0.0}
              gRPCPort: ${SW_RECEIVER_JAEGER_PORT:14250}
          ?
          query:
            selector: ${SW_QUERY:graphql}
            graphql:
              path: ${SW_QUERY_GRAPHQL_PATH:/graphql}
          ?
          alarm:
            selector: ${SW_ALARM:default}
            default:
          ?
          telemetry:
            selector: ${SW_TELEMETRY:none}
            none:
            prometheus:
              host: ${SW_TELEMETRY_PROMETHEUS_HOST:0.0.0.0}
              port: ${SW_TELEMETRY_PROMETHEUS_PORT:1234}
          ?
          configuration:
            selector: ${SW_CONFIGURATION:none}
            none:
            grpc:
              host: ${SW_DCS_SERVER_HOST:""}
              port: ${SW_DCS_SERVER_PORT:80}
              clusterName: ${SW_DCS_CLUSTER_NAME:SkyWalking}
              period: ${SW_DCS_PERIOD:20}
            apollo:
              apolloMeta: ${SW_CONFIG_APOLLO:http://106.12.25.204:8080}
              apolloCluster: ${SW_CONFIG_APOLLO_CLUSTER:default}
              apolloEnv: ${SW_CONFIG_APOLLO_ENV:""}
              appId: ${SW_CONFIG_APOLLO_APP_ID:skywalking}
              period: ${SW_CONFIG_APOLLO_PERIOD:5}
            zookeeper:
              period: ${SW_CONFIG_ZK_PERIOD:60} # Unit seconds, sync period. Default fetch every 60 seconds.
              nameSpace: ${SW_CONFIG_ZK_NAMESPACE:/default}
              hostPort: ${SW_CONFIG_ZK_HOST_PORT:localhost:2181}
              # Retry Policy
              baseSleepTimeMs: ${SW_CONFIG_ZK_BASE_SLEEP_TIME_MS:1000} # initial amount of time to wait between retries
              maxRetries: ${SW_CONFIG_ZK_MAX_RETRIES:3} # max number of times to retry
            etcd:
              period: ${SW_CONFIG_ETCD_PERIOD:60} # Unit seconds, sync period. Default fetch every 60 seconds.
              group: ${SW_CONFIG_ETCD_GROUP:skywalking}
              serverAddr: ${SW_CONFIG_ETCD_SERVER_ADDR:localhost:2379}
              clusterName: ${SW_CONFIG_ETCD_CLUSTER_NAME:default}
            consul:
              # Consul host and ports, separated by comma, e.g. 1.2.3.4:8500,2.3.4.5:8500
              hostAndPorts: ${SW_CONFIG_CONSUL_HOST_AND_PORTS:1.2.3.4:8500}
              # Sync period in seconds. Defaults to 60 seconds.
              period: ${SW_CONFIG_CONSUL_PERIOD:1}
              # Consul aclToken
              aclToken: ${SW_CONFIG_CONSUL_ACL_TOKEN:""}
          ?
          exporter:
            selector: ${SW_EXPORTER:-}
            grpc:
              targetHost: ${SW_EXPORTER_GRPC_HOST:127.0.0.1}
              targetPort: ${SW_EXPORTER_GRPC_PORT:9870}
          ?


          啟動

          要確保已經(jīng)啟動了elasticsearch,并且防火墻開放8080、11800、12800端口。

          進入bin目錄,執(zhí)行命令即可運行:

          ./startup.sh

          默認的UI端口是8080

          部署微服務(wù)探針

          現(xiàn)在,Skywalking的服務(wù)端已經(jīng)啟動完成,我們還需要在微服務(wù)中加入服務(wù)探針,來收集數(shù)據(jù)。

          解壓

          首先,將課前資料給的壓縮包解壓:

          將其中的agent解壓到某個目錄,不要出現(xiàn)中文,可以看到其結(jié)構(gòu)如下:

          其中有一個skywalking-agent.jar就是一我們要用的探針。

          配置

          如果是運行一個jar包,可以在運行時輸入?yún)?shù)來指定探針:

          java -jar xxx.jar -javaagent:C:/lesson/skywalking-agent/skywalking-agent.jar -Dskywalking.agent.service_name=ly-registry -Dskywalking.collector.backend_service=192.168.150.101:11800

          本例中,我們用開發(fā)工具來運行和配置。

          使用IDEA開發(fā)工具打開一個你的項目,在IDEA工具中,選擇要修改的啟動項,點擊右鍵,選擇Edit Configuration:

          然后在彈出的窗口中,點擊Environment,選擇VM options后面對應(yīng)的展開按鈕:

          在展開的輸入框中,輸入下面的配置:

          -javaagent:C:/lesson/skywalking-agent/skywalking-agent.jar
          -Dskywalking.agent.service_name=ly-registry
          -Dskywalking.collector.backend_service=192.168.150.101:11800

          注意:

          • -javaagent:C:/lesson/skywalking-agent/skywalking-agent.jar:配置的是skywalking-agent.jar這個包的位置,要修改成你自己存放的目錄
          • -Dskywalking.agent.service_name=ly-registry:是當前項目的名稱,需要分別修改為ly-registry、ly-gateway、ly-item-service
          • -Dskywalking.collector.backend_service=192.168.150.101:11800:是Skywalking的OPA服務(wù)地址,采用的是GRPC通信,因此端口是11800,不是8080

          啟動

          Skywalking的探針會在項目啟動前對class文件進行修改,完成探針植入,對業(yè)務(wù)代碼零侵入,所以我們只需要啟動項目,即可生效了。

          啟動項目,然后對項目中的的業(yè)務(wù)接口訪問,探針就開始工作了。

          WebUI界面

          訪問:192.168.150.101:8080可以看到統(tǒng)計數(shù)據(jù)已經(jīng)出來了:

          服務(wù)實例的性能監(jiān)控:

          服務(wù)拓撲圖:

          某次請求的鏈路追蹤信息:

          表格視圖:

          構(gòu)圖

          整個系統(tǒng)分為三部分:

          • agent:采集tracing(調(diào)用鏈數(shù)據(jù))和metric(指標)信息并上報
          • OAP:收集tracing和metric信息通過analysis core模塊將數(shù)據(jù)放入持久化容器中(ES,H2(內(nèi)存數(shù)據(jù)庫),mysql等等),并進行二次統(tǒng)計和監(jiān)控告警
          • webapp(UI):前后端分離,前端負責(zé)呈現(xiàn),并將查詢請求封裝為graphQL提交給后端,后端通過ribbon做負載均衡轉(zhuǎn)發(fā)給OAP集群,再將查詢結(jié)果渲染展示

          鏡像版本選擇

          本次提供了8.0.0和6.6.0的部署文件,主要是3個鏡像文件。由于官方提供的部署方式是Helm的,所以我們自己去Docker Hub上找到官方鏡像,編寫yaml文件來部署

          選擇ui和oap相匹配的版本,注意oap有es版本,因為官方默認也是用es來做存儲的,所以我們也采用es的版本

          1. apache/skywalking-oap-server:6.6.0-es7 or apache/skywalking-oap-server:8.0.0-es7
          2. apache/skywalking-ui:6.6.0 or apache/skywalking-ui:8.0.0

          由于agent官方是沒有提供鏡像的,需要我們?nèi)ス俜桨l(fā)行版中找到agent的文件,自己制作鏡像

          下載地址 skywalking.apache.org/downloads/ 選擇對應(yīng)的版本下載

          關(guān)于鏡像需要了解的點就這些

          k8s 部署要點

          通過deployment部署 OAP 和 UI服務(wù),通過Side Car模式把agent掛載到微服務(wù)應(yīng)用里面,對應(yīng)用代碼零侵入,而且不限制原來應(yīng)用的語言。OAP需要提供的配置文件通過ConfigMap注入,包括

          1. application.yml 應(yīng)用配置
          2. alarm-settings.yml 告警規(guī)則配置
          3. log4j2.xml 日志格式配置,為了ELK采集

          OAP

          端口映射,主要是grpc和rest

          grpc是代理接入,數(shù)據(jù)推送和遠程調(diào)用需要使用到的,比較重要

          rest是使用官方GraphQL API的端口,詳情查看 github.com/apache/skyw…

          ports:
          - containerPort: 11800
            name: grpc
            protocol: TCP
          - containerPort: 12800
            name: rest
            protocol: TCP
          復(fù)制代碼

          環(huán)境變量

          如果是部署6.X版本,需要加上這句話

          - name: SW_L0AD_CONFIG_FILE_FROM_VOLUME
            value: "true"
          復(fù)制代碼

          原因是在6.X的官方鏡像中,啟動腳本docker-entrypoint.sh中,有這么一段邏輯

          if [[ -z "$SW_L0AD_CONFIG_FILE_FROM_VOLUME" ]] || [[ "$SW_L0AD_CONFIG_FILE_FROM_VOLUME" != "true" ]]; then
              generateApplicationYaml
              echo "Generated application.yml"
              echo "-------------------------"
              cat ${var_application_file}
              echo "-------------------------"
          fi
          復(fù)制代碼

          沒有環(huán)境變量的話,將使用系統(tǒng)生成的配置文件,我們注入的配置文件就失效了,會導(dǎo)致服務(wù)無法啟動

          java agent

          skywalking的數(shù)據(jù)采集是采用服務(wù)推送的模式,數(shù)據(jù)指標推送給OAP服務(wù)處理。有多種實現(xiàn)方式,基于代理的實現(xiàn)方式是對系統(tǒng)侵入比較小的,通過Side Car模式來實現(xiàn)代理也是微服務(wù)架構(gòu)中常用的模式

          制作鏡像的時候,我們只需要把文件復(fù)制到鏡像中就行了

          FROM busybox:latest 
          
          RUN mkdir -p /opt/skywalking/agent/
          
          ADD agent/ /opt/skywalking/agent/
          
          WORKDIR /
          復(fù)制代碼

          使用agent,通過initContainers把agent掛載到volume中

          initContainers:
          - name: init-agent
            image: xxx.com/skywalking-agent:latest
            command:
            - 'sh'
            - '-c'
            - 'set -ex;mkdir -p /skywalking/agent;cp -r /opt/skywalking/agent/* /skywalking/agent;'
            volumeMounts:
            - name: agent
              mountPath: /skywalking/agent
          復(fù)制代碼

          然后通過commod覆蓋容器的啟動命令

          command: ["/bin/bash", "-c", "java -javaagent:/opt/skywalking/agent/skywalking-agent.jar -Dskywalking.agent.service_name=xxx-user -Dskywalking.collector.backend_service=$SKYWALKING_ADDR -jar /app.jar"]
          復(fù)制代碼

          這里涉及到Docker的ENTRYPOINT,CMD 和 k8s yaml 的 command 和 agrs的運用,

          由于命令和參數(shù)分割比較難處理,推薦統(tǒng)一使用命令,因為服務(wù)也不會存在加參數(shù)的情況。

          Docker的ENTRYPOINT就對應(yīng)了yaml的command,通過commod來覆蓋容器本身的啟動命令,

          所以需要注意的就是容器啟動有沒有什么特殊性,比如是通過腳本啟動的,直接通過java -jar的方式還不行,根據(jù)實際情況做調(diào)整

          參數(shù)含義:

          1. javaagent Java本身的規(guī)范,指定代理路徑
          2. Dskywalking.agent.service_name 服務(wù)在skywalking中展示的名稱
          3. Dskywalking.collector.backend_service 連接 OAP 服務(wù) grpc 的地址

          agent本身的配置

          主要是對agent如何采集數(shù)據(jù)的配置,這個配置在agent/config/agent.config下,所以在鏡像構(gòu)建的時候就要配置好,也可以通過環(huán)境變量注入

          環(huán)境變量注入思路:agent.config可以讀取環(huán)境變量的值,所以我們在dockerfile或者yaml中注入環(huán)境變量可以替換agent的參數(shù)

          配置參考:github.com/VanLiuZhi/d…

          忽略采集端點

          1. 在agent下,將apache-skywalking-apm-bin-es7\agent\optional-plugins\apm-trace-ignore-plugin-6.6.0.jar復(fù)制到apache-skywalking-apm-bin-es7\agent\plugins
          2. apache-skywalking-apm-bin-es7\agent\config下面新建一個配置文件 apm-trace-ignore-plugin.config,內(nèi)容為 trace.ignore_path=${SW_AGENT_TRACE_IGNORE_PATH:/healthy/**}

          這樣就可以忽略 healthy/** 端點

          配置文件

          下面對配置文件做一個概述,我們可以參考原始鏡像的目錄來調(diào)整掛載路徑,最好不要把整個目錄都覆蓋了,只掛載需要替換的配置文件是比較合理的做法。具體的配置文件可以從鏡像內(nèi)部獲取,或者參考官方發(fā)行版的配置

          application.yml

          cluster 配置

          主要是配置OAP服務(wù)的部署模式,這里采用k8s來部署集群,通過修改副本數(shù)就可以實現(xiàn)服務(wù)高可用

          kubernetes:
            watchTimeoutSeconds: ${SW_CLUSTER_K8S_WATCH_TIMEOUT:60}
            namespace: ${SW_CLUSTER_K8S_NAMESPACE:skywalking-min}
            labelSelector: ${SW_CLUSTER_K8S_LABEL:app=oap}
            uidEnvName: ${SW_CLUSTER_K8S_UID:SKYWALKING_COLLECTOR_UID}
          復(fù)制代碼

          修改選擇標簽到對應(yīng)的OAP deployment。另外注意使用k8s作為集群模式,需要提供k8s RBAC 訪問權(quán)限,經(jīng)過測試,在8.0.0版本下,沒有訪問權(quán)限的話無法使用k8s來部署集群

          storage 配置,數(shù)據(jù)存儲位置

          注意是es的地址和賬號密碼,nameSpace的作用是在索引前面加前綴,方便區(qū)分集群中的其它索引。調(diào)整副本和分片數(shù),指定數(shù)據(jù)存儲時間recordDataTTL

          storage:
            elasticsearch7:
              nameSpace: "eos_sw"
              clusterNodes: ${SW_STORAGE_ES_CLUSTER_NODES:10.90.xx.xx:9200}
              protocol: ${SW_STORAGE_ES_HTTP_PROTOCOL:"http"}
              # trustStorePath: ${SW_SW_STORAGE_ES_SSL_JKS_PATH:"../es_keystore.jks"}
              # trustStorePass: ${SW_SW_STORAGE_ES_SSL_JKS_PASS:""}
              user: ${SW_ES_USER:"elastic"}
              password: ${SW_ES_PASSWORD:"123456"}
              indexShardsNumber: ${SW_STORAGE_ES_INDEX_SHARDS_NUMBER:1}
              indexReplicasNumber: ${SW_STORAGE_ES_INDEX_REPLICAS_NUMBER:1}
              # Those data TTL settings will override the same settings in core module.
              recordDataTTL: ${SW_STORAGE_ES_RECORD_DATA_TTL:3} # Unit is day
              otherMetricsDataTTL: ${SW_STORAGE_ES_OTHER_METRIC_DATA_TTL:45} # Unit is day
              monthMetricsDataTTL: ${SW_STORAGE_ES_MONTH_METRIC_DATA_TTL:18} # Unit is month
              # Batch process setting, refer to https://www.elastic.co/guide/en/elasticsearch/client/java-api/5.5/java-docs-bulk-processor.html
              bulkActions: ${SW_STORAGE_ES_BULK_ACTIONS:1000} # Execute the bulk every 1000 requests
              flushInterval: ${SW_STORAGE_ES_FLUSH_INTERVAL:10} # flush the bulk every 10 seconds whatever the number of requests
              concurrentRequests: ${SW_STORAGE_ES_CONCURRENT_REQUESTS:2} # the number of concurrent requests
              resultWindowMaxSize: ${SW_STORAGE_ES_QUERY_MAX_WINDOW_SIZE:10000}
              metadataQueryMaxSize: ${SW_STORAGE_ES_QUERY_MAX_SIZE:5000}
              segmentQueryMaxSize: ${SW_STORAGE_ES_QUERY_SEGMENT_SIZE:200}
          復(fù)制代碼

          關(guān)于application的配置需要注意的一點就是各個版本的配置是有一定出入的,比如8.X和6.X版本的es存儲配置就不一樣,所以建議從官方發(fā)行版下載文件,參考文件來修改

          alarm-settings.yml

          告警配置

          舉例:監(jiān)控服務(wù)響應(yīng)時間

          # 規(guī)則名稱
          service_instance_resp_time_rule:
            # 指定采集度量,service_instance_resp_time 是通過OAL查詢定義的一個度量
            metrics-name: service_instance_resp_time
            op: ">"
            # 閾值
            threshold: 10
            # 周期
            period: 10
            # 次數(shù)
            count: 2
            # 告警后靜默時間
            silence-period: 5
            message: Response time of service instance {name} is more than 10ms in 2 minutes of last 10 minutes
          復(fù)制代碼

          官方的描述:閾值被設(shè)置為10毫秒,基本請求很容易到達閾值。周期是10分鐘,次數(shù)是2次。最近2分鐘內(nèi)的平均響應(yīng)時間超過10毫秒就告警,告警觸發(fā)后,沉默5分鐘后才會告警

          官方的描述中,總覺得period周期這個概念沒有體現(xiàn),當然也可能是中文翻譯的問題,上面的message部分就是官方原文描述,個人結(jié)合實際測試的理解:

          period是周期,是評判的范圍,單位是分鐘,現(xiàn)在設(shè)置為10,那么count次數(shù)就是在10分鐘內(nèi)如果有2次指標超過閾值,就會觸發(fā)告警,然后靜默5分鐘, 繼續(xù)循環(huán)。10分鐘的范圍,假設(shè)前30秒就有2次達到閾值,那么就會觸發(fā)告警,接著進入沉默期,然后繼續(xù)判斷。 如果10分鐘的范圍內(nèi)只有1次,等待11分鐘的時候又有一次,那么不告警。沉默期為0也不會馬上發(fā),最少間隔1分鐘

          實際測試的結(jié)果:

          silence-period 的配置,這個配置決定了告警后靜默時間,假如當前服務(wù)一直有問題,而且silence-period = 0 ,那么1分鐘推送一次告警。如果silence-period = 1,那么就是2分鐘推送一次告警(建立在當前服務(wù)一直有問題的前提下)

          可以監(jiān)控的指標:

          1. 服務(wù)監(jiān)控
          2. 實例監(jiān)控
          3. 服務(wù)與服務(wù)之間監(jiān)控
          4. 實例與實例之間監(jiān)控
          5. 端點監(jiān)控(就是接口路徑)
          6. 端點和端點之間監(jiān)控
          7. JVM和數(shù)據(jù)庫訪問監(jiān)控

          OAL示例:

          // 計算 Endpoint1 和 Endpoint2 的 p99 值
          Endpoint_p99 = from(Endpoint.latency).filter(name in ("Endpoint1", "Endpoint2")).summary(0.99)
          
          // 計算端點名以 `serv` 開頭的端點的 p99 值
          serv_Endpoint_p99 = from(Endpoint.latency).filter(name like ("serv%")).summary(0.99)
          
          // 計算每個端點的響應(yīng)平均時長
          Endpoint_avg = from(Endpoint.latency).avg()
          
          // 計算每個端點 p50, p75, p90, p95 and p99 的延遲柱狀圖, 每隔 50 毫秒一條柱
          Endpoint_percentile = from(Endpoint.latency).percentile(10)
          
          // 統(tǒng)計每個服務(wù)響應(yīng)狀態(tài)為 true 的百分比
          Endpoint_success = from(Endpoint.*).filter(status = "true").percent()
          
          // 統(tǒng)計每個服務(wù)響應(yīng)碼在 [200, 299] 之間的百分比
          Endpoint_200 = from(Endpoint.*).filter(responseCode like "2%").percent()
          
          // 統(tǒng)計每個服務(wù)響應(yīng)碼在 [500, 599] 之間的百分比
          Endpoint_500 = from(Endpoint.*).filter(responseCode like "5%").percent()
          
          // 統(tǒng)計每個服務(wù)的調(diào)用總量
          EndpointCalls = from(Endpoint.*).sum()
          
          disable(segment);
          disable(endpoint_relation_server_side);
          disable(top_n_database_statement);
          復(fù)制代碼

          在6.5.0之后的版本中,可以通過配置中心來動態(tài)修改告警規(guī)則配置

          skywalking

          官方中文翻譯:github.com/SkyAPM/docu…

          快速搭建:skywalking.apache.org/zh/blog/202…

          -Dskywalking.agent.service_name=skywalking-test-local -Dskywalking.collector.backend_service=127.0.0.1:11800 -javaagent:D:\JavaLearProject\apache-skywalking-apm-bin-es7\agent\skywalking-agent.jar

          概念

          Backend的gRPC相關(guān)的API可訪問0.0.0.0/11800,rest相關(guān)的API可訪問0.0.0.0/12800

          啟動模式

          啟動模式 在不同的部署工具(如K8S)中,可能需要不同的啟動模式。 我們還提供另外兩種可選的啟動模式。

          默認模式 默認模式。如果需要,進行初始化工作,啟動監(jiān)聽并提供服務(wù)。

          運行 /bin/oapService.sh(.bat) 來啟動這個模式。也可以在使用 startup.sh(.bat)來啟動。

          初始化模式 在此模式下,OAP服務(wù)器啟動以執(zhí)行初始化工作,然后退出。 您可以使用此模式初始化存儲,例如ElasticSearch索引、MySQL和TIDB表,和init數(shù)據(jù)。

          運行 /bin/oapServiceInit.sh(.bat) 來啟動這個模式。

          非初始化模式 在此模式下,OAP服務(wù)器不進行初始化。 但它等待存在彈性搜索索引、mysql和tidb表,開始傾聽并提供服務(wù)。意味著此OAP服務(wù)希望別的OAP服務(wù)器進行初始化。

          運行 /bin/oapServiceNoInit.sh(.bat) 來啟動這個模式。

          配置文件

          application.yml 作為核心配置文件

          Level 1, 模塊名。模塊定義項。 Level 2, 模塊類型。 設(shè)置模塊類型。 Level 3. 類型屬性。

          storage:
            selector: mysql # the mysql storage will actually be activated, while the h2 storage takes no effect
            h2:
              driver: ${SW_STORAGE_H2_DRIVER:org.h2.jdbcx.JdbcDataSource}
              url: ${SW_STORAGE_H2_URL:jdbc:h2:mem:skywalking-oap-db}
              user: ${SW_STORAGE_H2_USER:sa}
              metadataQueryMaxSize: ${SW_STORAGE_H2_QUERY_MAX_SIZE:5000}
            mysql:
              properties:
                jdbcUrl: ${SW_JDBC_URL:"jdbc:mysql://localhost:3306/swtest"}
                dataSource.user: ${SW_DATA_SOURCE_USER:root}
                dataSource.password: ${SW_DATA_SOURCE_PASSWORD:root@1234}
                dataSource.cachePrepStmts: ${SW_DATA_SOURCE_CACHE_PREP_STMTS:true}
                dataSource.prepStmtCacheSize: ${SW_DATA_SOURCE_PREP_STMT_CACHE_SQL_SIZE:250}
                dataSource.prepStmtCacheSqlLimit: ${SW_DATA_SOURCE_PREP_STMT_CACHE_SQL_LIMIT:2048}
                dataSource.useServerPrepStmts: ${SW_DATA_SOURCE_USE_SERVER_PREP_STMTS:true}
              metadataQueryMaxSize: ${SW_STORAGE_MYSQL_QUERY_MAX_SIZE:5000}
            # other configurations
          復(fù)制代碼

          storage is the 模塊名 selector 模塊類型. default 模塊默認屬性. driver, url, ... metadataQueryMaxSize 類型屬性.

          同時,模塊包括必修模塊和可選模塊,必修模塊提供后端框架, 即使模塊化支持可插拔,刪除這些模塊是沒有意義的,對于可選模塊,其中一些有 一個名為“none”的提供程序?qū)崿F(xiàn),這意味著它只提供一個沒有實際邏輯的shell,典型的例子是telemetry。 將“-”設(shè)置為“selector”意味著在運行時將排除整個模塊。 我們強烈建議您不要嘗試更改這些模塊的api,除非你非常了解SkyWalking項目及其代碼。

          必須的模塊列表

          Core。做所有數(shù)據(jù)分析和流調(diào)度的基本和主要框架。 Cluster。管理集群中的多個后端實例,這可以提供高吞吐量的處理能力。 Storage。持久化分析結(jié)果。 Query。提供查詢接口給UI。 對于Cluster 和Storage 有多個實現(xiàn)者(提供者), 查看 Cluster management 和 Choose storage 的link list文檔。

          一些receiver 模塊也提供了。 Receiver是一個模塊,負責(zé)接受后端的傳入數(shù)據(jù)請求。大多數(shù)(所有)通過一些rpc協(xié)議,如GRPC和HTTPrestful提供。 Receiver有許多不同的模塊名,你可以閱讀link list中的Set receivers文檔。

          k8s 中java進程

          java -Dapp.id=spring-demo -javaagent:/opt/skywalking/agent/skywalking-agent.jar -Dskywalking.agent.service_name=spring-demo -Dskywalking.collector.backend_service=oap:11800 -jar /app/app.jar

          告警

          實體名稱 定義范圍和實體名稱之間的關(guān)系.

          服務(wù): 服務(wù)名稱 實例: {服務(wù)名稱} 的 {實例名稱} 端點: {服務(wù)名稱} 中的 {端點名稱} 數(shù)據(jù)庫: 數(shù)據(jù)庫服務(wù)名 服務(wù)關(guān)系: {源服務(wù)名稱} 到 {目標服務(wù)名稱} 實例關(guān)系: {源服務(wù)名稱} 的 {源實例名稱} 到 {目標服務(wù)名稱} 的 {目標實例名稱} 端點關(guān)系: {源服務(wù)名稱} 中的 {源端點名稱} 到 {目標服務(wù)名稱} 中的 {目標端點名稱}

          觸發(fā)告警條件:由周期,次數(shù),沉默期來共同決定

          官方描述:

          端點平均響應(yīng)時間在最近 2 分鐘內(nèi)超過1秒

          service_instance_resp_time_rule:
              metrics-name: service_instance_resp_time
              op: ">"
              threshold: 1000
              period: 10
              count: 2
              silence-period: 5
              message: Response time of service instance {name} is more than 1000ms in 2 minutes of last 10 minutes
          復(fù)制代碼

          舉例:監(jiān)控服務(wù)響應(yīng)時間

          metrics-name: service_instance_resp_time
          op: ">"
          threshold: 10
          period: 10
          count: 2
          silence-period: 5
          復(fù)制代碼

          閾值被設(shè)置為10毫秒,基本請求很容易到達閾值。周期是10分鐘,次數(shù)是2次。最近2分鐘內(nèi)的平均響應(yīng)時間超過10毫秒就告警,告警觸發(fā)后,沉默5分鐘后才會告警,這是官方的描述

          個人結(jié)合實際測試的理解:period是周期,是評判的范圍,單位是分鐘,現(xiàn)在設(shè)置為10,那么count次數(shù)就是在10分鐘內(nèi)如果有2次指標超過閾值,就會觸發(fā)告警,然后靜默5分鐘。繼續(xù)循環(huán)

          10分鐘的范圍,假設(shè)前30秒就有2次達到閾值,那么就會觸發(fā)告警,接著進入沉默期,然后繼續(xù)判斷 如果10分鐘的范圍內(nèi)只有1次,等待11分鐘的時候又有一次,那么不告警。沉默期為0也不會馬上發(fā),最少間隔1分鐘

          實際測試的結(jié)果:

          silence-period 的配置,這個配置決定了告警后靜默時間,假如當前服務(wù)一直有問題,而且silence-period = 0 ,那么1分鐘推送一次告警。如果silence-period = 1,那么就是2分鐘推送一次告警(建立在當前服務(wù)一直有問題的前提下)

          監(jiān)控頁面UI指標概念

          CPM: 每分鐘請求調(diào)用的次數(shù) SLA: 服務(wù)等級協(xié)議(簡稱:SLA,全稱:service level agreement)

          是在一定開銷下為保障服務(wù)的性能和可用性。

          網(wǎng)站服務(wù)可用性SLA,9越多代表全年服務(wù)可用時間越長服務(wù)更可靠,停機時間越短

          1年 = 365天 = 8760小時

          99.9 = 8760 * 0.1% = 8760 * 0.001 = 8.76小時

          99.99 = 8760 * 0.0001 = 0.876小時 = 0.876 * 60 = 52.6分鐘

          99.999 = 8760 * 0.00001 = 0.0876小時 = 0.0876 * 60 = 5.26分鐘

          從以上看來,全年停機5.26分鐘才能做到99.999%,即5個9

          百分位數(shù):skywalking中有P50,P90,P95這種統(tǒng)計口徑,就是百分位數(shù)的概念。

          例如,p99 520 表示過去 1% 請求的平均延遲為 0.52 秒,99%的請求低于 0.52;p95 300 表示 95%的請求響應(yīng)時間低于 0.3 秒

          應(yīng)用性能指數(shù)(APDEX)通過計算分數(shù)來反映系統(tǒng)狀況,計算規(guī)則由多個指標組成

          k8s部署

          總共用到下面這幾個文件,目前官方的部署是基于helm來做的,只能自己編寫yaml文件了

          使用官方最新版 8.0.0 版本鏡像,8.0.0-es7(oap) 8.0.0(ui)

          skywalking-min-oap-configmap.yaml skywalking-min-oap-deployment.yaml skywalking-min-oap-namespace.yaml skywalking-min-oap-service.yaml skywalking-min-oap-serviceaccount.yaml skywalking-min-ui-deployment.yaml skywalking-min-ui-service.yaml

          具體分為兩個模塊,oap和ui

          其中ui比較簡單,連接oap:12800服務(wù)即可

          oap涉及到兩個端口,暴露這兩個端口

          1. grpc 11800 提供遠程調(diào)用,代理接入
          2. rest 12800 提供GraphQL API

          然后掛載配置文件,從源碼上拷貝配置文件,并通過configmap掛載,注意只掛載自己需要的,具體掛載文件內(nèi)容和路徑參考容器自身情況 一般只需要掛載配置文件和告警規(guī)則文件,如果需要定制日志,那么再掛載log配置文件

          配置文件注意:

          主要是storage存儲配置,這里采用es,需要修改es配置

          然后集群模式采用k8s的服務(wù)發(fā)現(xiàn),為此需要k8s rbac服務(wù),在yaml中有定義一個service-account,不然沒有訪問權(quán)限無法使用k8s做集群模式

          ES調(diào)整

          具體參考es部分

          1. 需要調(diào)整分片數(shù)大小,通過kibana
          PUT /_cluster/settings
          {
            "persistent": {
              "cluster": {
                "max_shards_per_node":10000
              }
            }
          }
          復(fù)制代碼
          1. 調(diào)整max_buckets 過小異常
          2. 配置文件修改后重啟,寫入線程大小修改: thread_pool.write.queue_size: 1000
          3. 調(diào)用鏈優(yōu)化:index.max_result_window: 1000000 默認只能返回10000,可能調(diào)用鏈太長需要修改這個配置

          鏈接:https://juejin.cn/post/7031823173498699784


          在本教程中,我們有一個使用 HTML、CSS 和 JS 制作的待辦事項列表應(yīng)用程序,我們將把它與 Cerbos 集成以向應(yīng)用程序添加授權(quán)。授權(quán)確定用戶是否可以執(zhí)行特定操作或訪問某些資源或數(shù)據(jù)。它使組織能夠控制和保護對敏感數(shù)據(jù)庫、私人和個人數(shù)據(jù)以及公司資源的訪問。在我們的 JS 應(yīng)用程序中,授權(quán)將定義用戶可以執(zhí)行的操作(創(chuàng)建待辦事項并閱讀待辦事項)以及管理員可以執(zhí)行的操作(創(chuàng)建、閱讀和刪除待辦事項)。

          RBAC 簡介

          基于角色的訪問控制 (RBAC)是一種訪問控制方法,它根據(jù)最終用戶的組織角色為其分配權(quán)限。RBAC 提供細粒度的控制,提供了一種簡單、易于管理的訪問管理方法,與單獨分配權(quán)限相比,這種方法不容易出錯。

          使用 RBAC 的優(yōu)點是管理授權(quán)權(quán)限變得更加容易,因為系統(tǒng)管理員可以批量管理用戶和權(quán)限,而不是逐個管理。
          我們已經(jīng)定義了 RBAC 策略,并將集成 Cerbos 以根據(jù)用戶身份授權(quán)創(chuàng)建、讀取和刪除待辦事項。我們對誰可以做什么的業(yè)務(wù)要求如下:

          • 管理員可以執(zhí)行所有操作(創(chuàng)建、讀取和刪除)
          • 用戶可以創(chuàng)建和閱讀待辦事項,但不能刪除待辦事項。

          什么是 Cerbos 以及為什么選擇 Cerbos?

          Cerbos 是一個開源授權(quán)層,可讓您輕松實現(xiàn)應(yīng)用程序的授權(quán)。在Cerbos,我們提供細粒度的訪問控制來增強安全性,同時使您的應(yīng)用程序更快、更具可擴展性。使用 Cerbos 進行授權(quán)具有使用嚴格的 JS 代碼無法獲得的各種優(yōu)勢

          • 更高的安全性:數(shù)字基礎(chǔ)設(shè)施面臨的威脅始終存在,訪問管理始終是一個緊迫的問題。當您在 JS 應(yīng)用程序中集成 Cerbos 授權(quán)時,您可以啟用細粒度的訪問控制,并通過幾行代碼安全地消除未經(jīng)授權(quán)的訪問。\
          • 可擴展性:Cerbos 擁有一個易于擴展的集中式策略管理系統(tǒng)。隨著應(yīng)用程序中用戶數(shù)量的增長,您的授權(quán)解決方案將隨應(yīng)用程序擴展,只需單擊幾下即可修改策略,而無需更改一行代碼。

          策略生成的最佳實踐

          當組織采用 RBAC 訪問模型時,必須遵守有關(guān)安全和管理的最佳實踐,并致力于不斷改進其訪問協(xié)議以防范新出現(xiàn)的威脅。

          以下列表包含一些您必須遵循的 RBAC 最佳實踐:

          1. 確定需求和角色:了解組織的特定需求并建立清晰的角色層次結(jié)構(gòu)。明確定義職責(zé)以指導(dǎo) RBAC 系統(tǒng)的設(shè)計。
          2. 制定和執(zhí)行政策:創(chuàng)建全面的 RBAC 政策,概述訪問規(guī)則、范圍和目標,并確保所有利益相關(guān)者都可以訪問它們。
          3. 應(yīng)用最小特權(quán)原則:僅為每個角色分配所需的最小權(quán)限,遵守最小特權(quán)原則以防止未經(jīng)授權(quán)的訪問。
          4. 定期審查和自動化:定期審查角色分配,以確保它們反映組織變化,并使用自動化進行有效的權(quán)限分配和刪除。
          5. 優(yōu)先監(jiān)控和響應(yīng):實施日志記錄和監(jiān)控以檢測可疑行為并制定事件響應(yīng)程序以迅速解決未經(jīng)授權(quán)的訪問。

          建模策略

          我們將在示例代碼中使用這些角色來演示訪問控制如何工作。

          使用 Cerbos,訪問規(guī)則始終面向資源,您編寫的策略會映射到系統(tǒng)中的這些資源。資源可以是任何東西,而您建模策略的方式則由您決定 — 您可以通過多種方式實現(xiàn)相同的邏輯結(jié)果:以操作為主導(dǎo)、以角色為主導(dǎo)、以屬性為主導(dǎo)或以它們的組合為主導(dǎo)。

          話雖如此,有些模式更適合特定場景——讓我們看看一些不同的方法。考慮這個權(quán)限模型:

          Actions

          Roles


          CPO

          CTO

          Exec-1

          Exec-2

          Exec-3

          View

          Allowed

          Allowed

          Allowed

          Allowed

          Allowed

          Add

          Allowed

          Allowed

          Allowed

          Allowed

          Allowed

          Delete

          Allowed

          Allowed

          Not Allowed

          Not Allowed

          Not Allowed

          我們將描述以行動為主導(dǎo)的政策,因為我們已經(jīng)為我們的 JS 應(yīng)用程序?qū)嵤┝艘孕袆訛橹鲗?dǎo)的政策。

          行動主導(dǎo)

          在這里,我們關(guān)注一個動作并列出可以執(zhí)行該動作的所有角色。為了更好地理解這一點,我們文檔中列出了一個示例,如下所示:

          # Principals in the following three roles can perform the `run` action
            - actions:
                - "run"
              effect: EFFECT_ALLOW
              roles:
                - JR_MANAGER
                - SR_MANAGER
                - CFO
          
          # All principals can perform the `view` action
            - actions:
                - "view"
              effect: EFFECT_ALLOW
              roles:
                - ["*"]
          

          如果您的系統(tǒng)符合以下任一情況,則此方法可能適用:

          • 您的角色在他們能做的事情上是“相似的”,例如 JR_MANAGER 和 SR_MANAGER;JR_MANAGER 可能擁有 SR_MANAGER 權(quán)限的子集。當然,在任何一個方向上都會有重復(fù),但從行動角度來推理這一點通常更容易。
          • 您有“高風(fēng)險”操作 — 您希望能夠一目了然地知道哪些角色有權(quán)訪問特定操作。明確列出每個操作的角色,可以大大減少意外向錯誤用戶授予不需要的權(quán)限的可能性。
          • 您擁有的角色數(shù)量相對較多,但操作數(shù)量較少。

          先決條件

          1. WSL(如果 Windows 是你的主要操作系統(tǒng))
          2. Docker

          在 JavaScript 應(yīng)用程序中集成 Cerbos

          1. 首先,克隆此存儲庫并繼續(xù)操作。確保您位于存儲庫的主分支中。

          我們的應(yīng)用程序的文件結(jié)構(gòu)

          構(gòu)建成功后,您應(yīng)該會看到網(wǎng)頁在瀏覽器的localhost:5500上加載。

          目前,沒有任何策略,此應(yīng)用程序中的 CPO 和 CTO 被授予刪除待辦事項的權(quán)限,而高管(1、2 和 3)只能查看和添加待辦事項。但是,由于我們尚未將 Cerbos 與應(yīng)用程序集成以進行權(quán)限管理,因此 CTO 和 CPO 無法刪除待辦事項。成功集成 Cerbos 后,CTO 和 CPO 將能夠刪除待辦事項。

          將 Cerbos 集成為服務(wù)

          要將 Cerbos 集成到我們的 JavaScript 應(yīng)用程序中,我們首先要啟動 Cerbos Docker 容器。在根目錄 (/to-dolist-cerbos) 中使用以下命令運行 Docker 容器:

          docker run --rm --name cerbos -d -v $(pwd)/cerbos/policies:/policies -p 3592:3592 -p 3593:3593 ghcr.io/cerbos/cerbos:0.34.0 
          

          使用 Cerbos RBAC 策略生成器生成策略文件

          Cerbos Playground是一款用于在線創(chuàng)建和測試策略的實用程序。Cerbos Playground 是了解策略創(chuàng)建甚至生成可用策略的絕佳方式:https://play.cerbos.dev/new ?generator 。

          如何使用 RBAC 策略生成器為我們的 javascript 應(yīng)用程序生成策略?

          我們有兩個角色:用戶和管理員(其中 CTO/CPO 是管理員,而高管是用戶)。添加操作并根據(jù)我們要授予的權(quán)限選擇復(fù)選框。

          根據(jù)偏好選擇后,我們可以點擊**生成**按鈕,生成一個名為to-dos.yaml的YAML策略文件。

          使用生成器生成策略后,只需將其復(fù)制并添加到應(yīng)用程序的文件結(jié)構(gòu)中即可。策略生成器還會生成一個 to-dos_test.yaml 文件,該文件旨在幫助自動測試訪問控制策略。確保測試文件始終以 _test 后綴結(jié)尾。以下是它通常包含的內(nèi)容和功能:

          現(xiàn)在我們已經(jīng)將 Cerbos 與 JS 應(yīng)用程序集成,我們將運行它來檢查策略是否按預(yù)期工作。

          測試我們的策略文件

          讓我們使用測試文件和 Cerbos RBAC 策略生成器生成的 _testdata _ 來測試策略文件。

          您可以使用此 Docker 命令(在 PowerShell 終端中)來運行測試:

          docker run -i -t -v "$(Get-Location)/cerbos/policies:/policies" ghcr.io/cerbos/cerbos:latest compile /policies
          

          運行此命令后,測試成功執(zhí)行。

          在應(yīng)用程序 UI 中生效的策略

          如果高管(具有角色:用戶)嘗試刪除待辦事項:

          隨著政策的實施,高管不得刪除待辦事項;他們會收到一條警告:您無權(quán)刪除此待辦事項。該權(quán)限僅授予 CPO 和 CTO 角色。

          根據(jù)政策,高管可以將待辦事項添加到列表中:

          將任務(wù)添加到文本框并單擊添加待辦事項按鈕將其添加到待辦事項列表中。

          CPO 已授權(quán),待辦事項已成功刪除。

          這個實際演示成功地描繪了 Cerbos 與我們的 JS 應(yīng)用程序的集成。

          經(jīng)常問的問題

          Q1. 制定 RBAC 政策時我們必須考慮哪些最佳實踐?

          A1:當組織采用 RBAC 訪問模型時,必須遵守有關(guān)安全和管理的最佳實踐,并致力于不斷改進其訪問協(xié)議,以防范新出現(xiàn)的威脅。

          以下列表包含 RBAC 最佳實踐的公平樣本:

          1. 確定需求:了解組織角色和職責(zé)以指導(dǎo) RBAC 設(shè)計。
          2. 生成政策:制定明確的 RBAC 政策,詳細說明規(guī)則、范圍和目標,并與利益相關(guān)者分享。
          3. 建立角色層次結(jié)構(gòu):定義與組織結(jié)構(gòu)相一致的角色和職責(zé)。
          4. 應(yīng)用最小權(quán)限:為每個角色授予最小權(quán)限以限制訪問。

          問題 2:在政策生效之前,可以使用 Cerbos 進行測試嗎?

          A2:是的,可以在策略生效之前使用 Cerbos 對其進行測試。Cerbos 提供強大的策略測試功能,允許您在將訪問控制規(guī)則部署到生產(chǎn)環(huán)境之前對其進行驗證。使用 Cerbos Policy Generator 中提供的 Cerbos 測試框架,您可以確保策略強制執(zhí)行所需的訪問控制規(guī)則并避免實際場景中的潛在問題。這種部署前測試有助于維護訪問控制策略的完整性和安全性,降低未經(jīng)授權(quán)訪問的風(fēng)險并確保遵守組織的安全準則。

          結(jié)論

          您已通過以下關(guān)鍵步驟成功將 Cerbos 集成到演示待辦事項列表應(yīng)用程序中:

          • 我們正在 Docker 容器中部署 Cerbos,以確保一致且隔離的環(huán)境。
          • 制定和完善策略文件以定義明確的訪問控制規(guī)則。
          • 重建應(yīng)用程序以納入這些政策。
          • 驗證應(yīng)用程序是否遵守既定的授權(quán)規(guī)則,確保安全和受控的訪問。

          主站蜘蛛池模板: 日韩成人一区ftp在线播放| 色偷偷一区二区无码视频| 少妇人妻偷人精品一区二区| 激情内射亚州一区二区三区爱妻| 国内精自品线一区91| 色综合久久一区二区三区| 亚洲国产一区二区视频网站| 精品视频一区二区三区四区 | 国产免费一区二区三区VR| 亚洲欧美日韩中文字幕在线一区| 怡红院一区二区三区| 国产精品亚洲一区二区无码| 国产精品一区二区av不卡| 亚洲AV成人一区二区三区AV| 国产精品亚洲一区二区三区| 日本免费电影一区二区| 日本强伦姧人妻一区二区| 亚洲熟妇无码一区二区三区| 日本中文字幕一区二区有码在线| 无码精品蜜桃一区二区三区WW | 亚洲片国产一区一级在线观看 | 国产伦精品一区二区三区视频金莲| 性色AV 一区二区三区| 一色一伦一区二区三区| 亚洲日本一区二区三区| 精品视频一区二区三区在线观看| 成人久久精品一区二区三区| 亚洲Av无码国产一区二区| 亚洲国产精品一区二区九九| 日本精品高清一区二区| 八戒久久精品一区二区三区| 亚洲国产综合无码一区二区二三区| 一区二区3区免费视频| 末成年女AV片一区二区| 成人免费一区二区三区在线观看| 国产亚洲福利精品一区二区| chinese国产一区二区| 免费看无码自慰一区二区| 国产成人一区二区三区| 亚洲Av高清一区二区三区| 美女视频免费看一区二区 |