溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何實踐Service Mesh微服務架構的基礎部署

發(fā)布時間:2021-11-19 13:39:06 來源:億速云 閱讀:186 作者:柒染 欄目:云計算

這篇文章將為大家詳細講解有關如何實踐Service Mesh微服務架構的基礎部署,文章內(nèi)容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。

當下,已經(jīng)有很大一部分公司完成了單體架構向微服務架構的遷移改造,并在疲于應對大量微服務間通信問題時,開始考慮采用Service Mesh微服務架構作為服務與服務直接通信的透明化管理框架,以插件式的方式實現(xiàn)各種業(yè)務所需的高級管理功能。

而開源PaaS Rainbond提供了開箱即用的Service Mesh微服務架構,部署在Rainbond上的應用原生即是Service Mesh微服務架構應用。

接下來,我們將以 Rainbond v3.7.0 為基礎平臺,以開源商城項目 sockshop 為例,演示如何在源代碼無入侵的情況下,將項目改造為具有服務注冊與發(fā)現(xiàn)、分布式跟蹤A/B測試、灰度發(fā)布、限流 、熔斷、 性能分析、高可用日志分析等能力的高可靠性電商業(yè)務系統(tǒng).

sockshop是一個典型的微服務架構案例,具備用戶管理、商品管理、購物車、訂單流程、地址管理等完善的電商相關功能。sockshop主要由Spring boot、Golang、Nodejs等多種語言開發(fā),使用MySQLMongoDB等多種數(shù)據(jù)庫,原方案采用單機環(huán)境下的部署方式,缺乏服務治理能力和分布式能力。

sockshop部署后的拓撲圖總覽

如何實踐Service Mesh微服務架構的基礎部署

sockshop商城首頁預覽圖

如何實踐Service Mesh微服務架構的基礎部署

sockshop架構圖

如何實踐Service Mesh微服務架構的基礎部署

更多信息

  • 源碼地址

  • weavesocksdemo 樣例

sockshop在Rainbond的部署流程

STEP1 服務創(chuàng)建

Rainbond支持從源碼、鏡像、應用市場等多種方式進行應用部署,這里我們采用DockerCompose配置文件的創(chuàng)建方式,批量創(chuàng)建 sockshop 中包含的所有服務。

  • docker-compose 創(chuàng)建

如何實踐Service Mesh微服務架構的基礎部署

需要注意的是,在檢測和創(chuàng)建過程中,獲取大量鏡像需要一定時間,請耐心等待完成!

  • docker-compose 源碼: 下載

version: '2'

services:
  front-end:
    image: weaveworksdemos/front-end:0.3.12
    hostname: front-end
    restart: always
    cap_drop:
      - all
    ports:
      - "8079:8079"
      - "9001:9001"
    depends_on:
      - catalogue
      - carts
      - payment
      - user
      - orders
  edge-router:
    image: weaveworksdemos/edge-router:0.1.1
    ports:
      - '80:80'
      - '8080:8080'
    cap_drop:
      - all
    cap_add:
      - NET_BIND_SERVICE
      - CHOWN
      - SETGID
      - SETUID
      - DAC_OVERRIDE
    tmpfs:
      - /var/run:rw,noexec,nosuid
    hostname: edge-router
    restart: always
    depends_on:
      - front-end
  catalogue:
    image: weaveworksdemos/catalogue:0.3.5
    hostname: catalogue
    restart: always
    cap_drop:
      - all
    cap_add:
      - NET_BIND_SERVICE
    depends_on:
      - catalogue-db
      - zipkin
  catalogue-db:
    image: rilweic/catalog-db
    hostname: catalogue-db
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
      - MYSQL_ALLOW_EMPTY_PASSWORD=true
      - MYSQL_DATABASE=socksdb
  carts:
    image: weaveworksdemos/carts:0.4.8
    hostname: carts
    restart: always
    cap_drop:
      - all
    cap_add:
      - NET_BIND_SERVICE
    tmpfs:
      - /tmp:rw,noexec,nosuid
    environment:
      - JAVA_OPTS=-Xms64m -Xmx128m -XX:+UseG1GC -Djava.security.egd=file:/dev/urandom -Dspring.zipkin.enabled=false
    ports:
      - "80:80"
    depends_on:
      - carts-db
      - zipkin
  carts-db:
    image: mongo:3.4
    hostname: carts-db
    restart: always
    cap_drop:
      - all
    cap_add:
      - CHOWN
      - SETGID
      - SETUID
    tmpfs:
      - /tmp:rw,noexec,nosuid
  orders:
    image: rilweic/orders
    hostname: orders
    restart: always
    cap_drop:
      - all
    cap_add:
      - NET_BIND_SERVICE
    tmpfs:
      - /tmp:rw,noexec,nosuid
    environment:
      - JAVA_OPTS=-Xms64m -Xmx128m -XX:+UseG1GC -Djava.security.egd=file:/dev/urandom -Dspring.zipkin.enabled=false
    ports:
      - "8848:8848"
    depends_on:
      - orders-db
      - zipkin
      - shipping
      - carts
      - payment
      - user
  orders-db:
    image: mongo:3.4
    hostname: orders-db
    restart: always
    cap_drop:
      - all
    cap_add:
      - CHOWN
      - SETGID
      - SETUID
    tmpfs:
      - /tmp:rw,noexec,nosuid
  shipping:
    image: Rainbond/shipping:0.4.8
    hostname: shipping
    restart: always
    cap_drop:
      - all
    cap_add:
      - NET_BIND_SERVICE
    tmpfs:
      - /tmp:rw,noexec,nosuid
    environment:
      - JAVA_OPTS=-Xms64m -Xmx128m -XX:+UseG1GC -Djava.security.egd=file:/dev/urandom -Dspring.zipkin.enabled=false
    ports:
      - "8080:8080"
    depends_on:
      - rabbitmq
      - zipkin
  queue-master:
    image: weaveworksdemos/queue-master:0.3.1
    hostname: queue-master
    restart: always
    cap_drop:
      - all
    cap_add:
      - NET_BIND_SERVICE
    tmpfs:
      - /tmp:rw,noexec,nosuid
    depends_on:
      - rabbitmq
  rabbitmq:
    image: rabbitmq:3.6.8
    hostname: rabbitmq
    restart: always
    cap_drop:
      - all
    cap_add:
      - CHOWN
      - SETGID
      - SETUID
      - DAC_OVERRIDE
  payment:
    image: weaveworksdemos/payment:0.4.3
    hostname: payment
    restart: always
    cap_drop:
      - all
    cap_add:
      - NET_BIND_SERVICE
    depends_on:
      - zipkin
  user:
    image: weaveworksdemos/user:0.4.4
    hostname: user
    restart: always
    cap_drop:
      - all
    cap_add:
      - NET_BIND_SERVICE
    environment:
      - MONGO_HOST=user-db:27017
    depends_on:
      - user-db
      - zipkin
  user-db:
    image: weaveworksdemos/user-db:0.4.0
    hostname: user-db
    restart: always
    cap_drop:
      - all
    cap_add:
      - CHOWN
      - SETGID
      - SETUID
    tmpfs:
      - /tmp:rw,noexec,nosuid
  zipkin:
    image: openzipkin/zipkin
    hostname: zipkin
    restart: always
    cap_drop:
      - all
    cap_add:
      - CHOWN
      - SETGID
      - SETUID
    tmpfs:
      - /tmp:rw,noexec,nosuid
    environment:
      - reschedule=on-node-failure
    ports:
      - "9411:9411"

源碼、應用市場等其他創(chuàng)建方式請參考Rainbond文檔:創(chuàng)建一個應用

服務創(chuàng)建完成后,我們需要對批量創(chuàng)建的服務進行注冊和對部署內(nèi)存的調(diào)整,根據(jù)服務之間的調(diào)用關系,分析出哪些服務是作為內(nèi)部服務供給其它服務調(diào)用、哪個服務是對用戶提供訪問的,并進行接下來的操作:

STEP2 服務注冊

在 Rainbond 平臺,我們可以通過在服務的端口頁打開端口來進行服務的注冊。關于服務注冊的詳細文檔可參考Rainbond 平臺服務注冊

各服務對應的端口和部署內(nèi)存大小如下:

如何實踐Service Mesh微服務架構的基礎部署

請注意,這里必須確定對每個服務組件的服務注冊信息和資源分配信息設置正確。

STEP3 服務發(fā)現(xiàn)

sockshop通過內(nèi)部域名來進行服務調(diào)用,也就是說,在完成服務的注冊后,調(diào)用服務需要發(fā)現(xiàn)被調(diào)用服務。

在 Rainbond 平臺,我們可以通過服務依賴來實現(xiàn)(詳情參考文檔服務發(fā)現(xiàn))。

各服務依賴的詳情可參考上圖商城在Rainbond平臺的概覽

如果使用上面的 docker-compose 文件創(chuàng)建應用,無需手動添加依賴,在創(chuàng)建應用時系統(tǒng)已根據(jù) docker-compose 文件內(nèi)容自動配置了服務發(fā)現(xiàn)

STEP4 服務 Mesh 治理

在sockshop案例中,front-endnodejs項目,該服務會調(diào)用其他 5 個服務來獲取數(shù)據(jù),如圖所示:

如何實踐Service Mesh微服務架構的基礎部署

front-end 在調(diào)用其他服務時,會使用域名+端口的調(diào)用方式(該項目所有調(diào)用均為此方式) 如 front-end 調(diào)用 orders 時,內(nèi)部訪問地址為 http://orders/xxx.

Rainbond 平臺在服務進行調(diào)用時,會默認將頂級域名解析到127.0.0.1,如果調(diào)用的服務對應的端口都不沖突沒有任何問題,而在此案例中,front-end調(diào)用的其他 5 個服務的端口均為 80。因此這里需要第一個治理功能:端口復用。

在不安裝 7 層網(wǎng)絡治理插件的情況下,平臺默認使用 4 層網(wǎng)絡治理插件,無法提供端口復用的機制。因此,我們?yōu)榉?code>front-end orders 分別安裝網(wǎng)絡治理插件。

STEP5 安裝網(wǎng)絡治理插件

我的插件中選擇服務網(wǎng)絡治理插件進行安裝。

如何實踐Service Mesh微服務架構的基礎部署

特別注意

工作在 7 層的 Mesh 插件默認會占用 80 端口,因此需要安裝此插件的服務本身不能占用 80 端口。因此我們推薦服務盡量監(jiān)聽非 80 端口。插件內(nèi)存使用量需要根據(jù)流量大小調(diào)節(jié)。

STEP6 應用安裝插件

在應用詳情頁面選擇插件標簽,然后開通指定的插件。

如何實踐Service Mesh微服務架構的基礎部署

Rainbond默認提供的服務網(wǎng)絡治理插件是基于Envoy制作,Rainbond ServiceMesh架構為Envoy提供了標準的運行支持。安裝插件后需重啟應用生效。

STEP7 Mesh 插件配置

配置域名路由,實現(xiàn)端口復用。為了front-end服務能根據(jù)代碼已有的域名調(diào)用選擇對應的服務提供方,我們需要根據(jù)其調(diào)用的域名來進行配置。將應用進行依賴后,服務網(wǎng)絡治理插件能夠自動識別出其依賴的應用。我們只需在插件的配置的域名項中進行域名配置即可。如下圖:

如何實踐Service Mesh微服務架構的基礎部署

詳細配置

如何實踐Service Mesh微服務架構的基礎部署

更新插件相關的配置后進行保存并重啟相關應用即可。此處暫時先只用到基于域名的路由配置,關于網(wǎng)絡治理插件的更對詳情可參考 服務路由,灰度發(fā)布,A/B 測試

STEP8 服務性能分析

微服務是一個分布式的架構模式,它一直以來都會有一些自身的問題。當一個應用的運行狀態(tài)出現(xiàn)異常時,對于運維和開發(fā)人員來說,即時發(fā)現(xiàn)應用的狀態(tài)異常并解決是非常有必要的。我們可以通過監(jiān)控手段對服務進行衡量,或者做一個數(shù)據(jù)支撐。

Rainbond 平臺為我們提供了服務監(jiān)控與性能監(jiān)控,可以簡單直觀的了解服務當前的狀態(tài)和信息。

目前支持 HTTP 與 mysql 協(xié)議的應用

  • 安裝插件

如何實踐Service Mesh微服務架構的基礎部署

  • 應用安裝插件

    同上應用網(wǎng)絡治理插件安裝

  • 安裝完成效果圖

    安裝完成性能分析插件,可以在安裝該插件的應用概覽頁面查看應用的平均響應時間吞吐率。

如何實踐Service Mesh微服務架構的基礎部署

除此以外,我們也可以在該組應用的組概覽中看到應用的訪問情況。

如何實踐Service Mesh微服務架構的基礎部署

  • 案例上的性能測試工具服務

    sockshop 商城案例自帶性能測試的服務,但是與該項目不是持續(xù)運行,而是運行一次后程序便會退出。在這里,我們根據(jù)源碼進行了一點小的修改。主要是將程序變?yōu)椴煌顺鲞\行。源碼地址

    我們可以通過源碼方式來創(chuàng)建項目——

如何實踐Service Mesh微服務架構的基礎部署

創(chuàng)建完成后,我們需要在 sockshop 商城創(chuàng)建一個賬號為user、密碼為password 的用戶,負載測試需要使用該用戶名來和密碼進行模擬請求。

完成以上步驟,接下來我們對sockshop的分布式跟蹤進行處理。

微服務分布式跟蹤

zipkin 簡介

隨著業(yè)務越來越復雜,系統(tǒng)也隨之進行各種拆分,特別是隨著微服務架構和容器技術的興起,看似簡單的一個應用,后臺可能有幾十個甚至幾百個服務在支撐;一個前端的請求可能需要多次的服務調(diào)用最后才能完成;當請求變慢或者不可用時,我們無法得知是哪個后臺服務引起的,這時就需要解決如何快速定位服務故障點,Zipkin 分布式跟蹤系統(tǒng)就能很好的解決這樣的問題。

Zipkin 分布式跟蹤系統(tǒng);它可以幫助收集時間數(shù)據(jù),解決在 microservice 架構下的延遲問題;它管理這些數(shù)據(jù)的收集和查找;Zipkin 的設計是基于谷歌的 Google Dapper 論文。 每個應用程序向 Zipkin 報告定時數(shù)據(jù),Zipkin UI 呈現(xiàn)了一個依賴圖表來展示多少跟蹤請求經(jīng)過了每個應用程序;如果想解決延遲問題,可以過濾或者排序所有的跟蹤請求,并且可以查看每個跟蹤請求占總跟蹤時間的百分比。

  • zipkin 架構

如何實踐Service Mesh微服務架構的基礎部署

裝配了 zipkin 跟蹤器的服務可以將服務的每次調(diào)用(可以是 http 或者 rpc 或數(shù)據(jù)庫調(diào)用等)延時通過Transport(目前有 4 總共發(fā)送方式,http,kafka,scribe,rabbitmq)發(fā)送給zipkin服務。

zipkin 主要包含 4 個模塊

collector: 接收或收集各應用傳輸?shù)臄?shù)據(jù)。 storage: 存儲接受或收集過來的數(shù)據(jù),當前支持 Memory,MySQL,Cassandra,ElasticSearch 等,默認存儲在內(nèi)存中。 API(Query): 負責查詢 Storage 中存儲的數(shù)據(jù),提供簡單的 JSON API 獲取數(shù)據(jù),主要提供給 web UI 使用 Web: 提供簡單的 web 界面

  • zipkin 服務追蹤流程

如何實踐Service Mesh微服務架構的基礎部署

從上圖可以簡單概括為一次請求調(diào)用,zipkin 會在請求中加入跟蹤的頭部信息和相應的注釋,并記錄調(diào)用的時間并將數(shù)據(jù)返回給 zipkin 的收集器 collector。

zipkin 安裝

在 Rinbond 平臺,我們可以直接通過 docker run 方式運行 zipkin.

如何實踐Service Mesh微服務架構的基礎部署

注意開啟對外訪問端口和調(diào)整應用內(nèi)存大小

此時創(chuàng)建的 zipkin 的數(shù)據(jù)存在于內(nèi)存中,服務關閉或重啟數(shù)據(jù)都會丟失。因此在生產(chǎn)環(huán)境中,我們需要將數(shù)據(jù)存入存儲。

zipkin 支持 MySQL,Cassandra,ElasticSearch 三種存儲。我們以 Mysql 為例說明。目前 zipkin 至此的 mysql 版本為 5.6 和 5.7 版本。

在 Rainbond 平臺應用市場創(chuàng)建版本為 5.7 的 mysql 應用,如圖。

如何實踐Service Mesh微服務架構的基礎部署

創(chuàng)建完成 mysql 以后,我們需要進行數(shù)據(jù)庫的初始化操作,zipkin 需要使用到 zipkin 數(shù)據(jù)和相應的表結構,需要我們自行創(chuàng)建。

在應用的詳情頁面,我們可以選擇管理容器進入到容器進行操作,如圖。

如何實踐Service Mesh微服務架構的基礎部署

進入容器后,使用命令登錄 mysql 命令行。

mysql -uusername -ppassword

mysql 的用戶和密碼可以在應用的依賴里看到 如圖

如何實踐Service Mesh微服務架構的基礎部署

進入 mysql 命令行后,創(chuàng)建數(shù)據(jù)庫 zipkin

CREATE DATABASE zipkin ;

創(chuàng)建 zipkin 相關的表:下載

CREATE TABLE IF NOT EXISTS zipkin_spans (
  `trace_id_high` BIGINT NOT NULL DEFAULT 0 COMMENT 'If non zero, this means the trace uses 128 bit traceIds instead of 64 bit',
  `trace_id` BIGINT NOT NULL,
  `id` BIGINT NOT NULL,
  `name` VARCHAR(255) NOT NULL,
  `parent_id` BIGINT,
  `debug` BIT(1),
  `start_ts` BIGINT COMMENT 'Span.timestamp(): epoch micros used for endTs query and to implement TTL',
  `duration` BIGINT COMMENT 'Span.duration(): micros used for minDuration and maxDuration query'
) ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE utf8_general_ci;

ALTER TABLE zipkin_spans ADD UNIQUE KEY(`trace_id_high`, `trace_id`, `id`) COMMENT 'ignore insert on duplicate';
ALTER TABLE zipkin_spans ADD INDEX(`trace_id_high`, `trace_id`, `id`) COMMENT 'for joining with zipkin_annotations';
ALTER TABLE zipkin_spans ADD INDEX(`trace_id_high`, `trace_id`) COMMENT 'for getTracesByIds';
ALTER TABLE zipkin_spans ADD INDEX(`name`) COMMENT 'for getTraces and getSpanNames';
ALTER TABLE zipkin_spans ADD INDEX(`start_ts`) COMMENT 'for getTraces ordering and range';

CREATE TABLE IF NOT EXISTS zipkin_annotations (
  `trace_id_high` BIGINT NOT NULL DEFAULT 0 COMMENT 'If non zero, this means the trace uses 128 bit traceIds instead of 64 bit',
  `trace_id` BIGINT NOT NULL COMMENT 'coincides with zipkin_spans.trace_id',
  `span_id` BIGINT NOT NULL COMMENT 'coincides with zipkin_spans.id',
  `a_key` VARCHAR(255) NOT NULL COMMENT 'BinaryAnnotation.key or Annotation.value if type == -1',
  `a_value` BLOB COMMENT 'BinaryAnnotation.value(), which must be smaller than 64KB',
  `a_type` INT NOT NULL COMMENT 'BinaryAnnotation.type() or -1 if Annotation',
  `a_timestamp` BIGINT COMMENT 'Used to implement TTL; Annotation.timestamp or zipkin_spans.timestamp',
  `endpoint_ipv4` INT COMMENT 'Null when Binary/Annotation.endpoint is null',
  `endpoint_ipv6` BINARY(16) COMMENT 'Null when Binary/Annotation.endpoint is null, or no IPv6 address',
  `endpoint_port` SMALLINT COMMENT 'Null when Binary/Annotation.endpoint is null',
  `endpoint_service_name` VARCHAR(255) COMMENT 'Null when Binary/Annotation.endpoint is null'
) ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE utf8_general_ci;

ALTER TABLE zipkin_annotations ADD UNIQUE KEY(`trace_id_high`, `trace_id`, `span_id`, `a_key`, `a_timestamp`) COMMENT 'Ignore insert on duplicate';
ALTER TABLE zipkin_annotations ADD INDEX(`trace_id_high`, `trace_id`, `span_id`) COMMENT 'for joining with zipkin_spans';
ALTER TABLE zipkin_annotations ADD INDEX(`trace_id_high`, `trace_id`) COMMENT 'for getTraces/ByIds';
ALTER TABLE zipkin_annotations ADD INDEX(`endpoint_service_name`) COMMENT 'for getTraces and getServiceNames';
ALTER TABLE zipkin_annotations ADD INDEX(`a_type`) COMMENT 'for getTraces';
ALTER TABLE zipkin_annotations ADD INDEX(`a_key`) COMMENT 'for getTraces';
ALTER TABLE zipkin_annotations ADD INDEX(`trace_id`, `span_id`, `a_key`) COMMENT 'for dependencies job';

CREATE TABLE IF NOT EXISTS zipkin_dependencies (
  `day` DATE NOT NULL,
  `parent` VARCHAR(255) NOT NULL,
  `child` VARCHAR(255) NOT NULL,
  `call_count` BIGINT,
  `error_count` BIGINT
) ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE utf8_general_ci;

ALTER TABLE zipkin_dependencies ADD UNIQUE KEY(`day`, `parent`, `child`);

在 zipkin 服務中添加環(huán)境變量 STORAGE_TYPEmysql,此變量標志 zipkin 使用的存儲方式??蛇x擇值為 mysql,elasticsearch、cassandra

將 zipkin 與 mysql 建立依賴關系后,zipkin 服務便安裝完成。

zipkin 內(nèi)部會默認調(diào)用環(huán)境變量 MYSQL_USER(用戶名),MYSQL_PASS(密碼),MYSQL_HOST(連接地址),MYSQL_PORT(端口)。剛好與 Rainbond 平臺默認設置的變量一致,所以無需做任何修改。

其他服務如果連接的變量與 Rainbond 平臺默認提供的不一致,我們可以在應用的設置也添加相應的環(huán)境變量來達到訪問的目的。

sockshop 中的 zipkin 案例

sockshop 案例集成了zipkin做分布式跟蹤。集成的組件為 users、cartsorders、paymentcatalogue、shipping。

其中 carts、ordersshippingspring-boot項目,只需在設置中將環(huán)境變量JAVA_OPTS-Dspring.zipkin.enabled改為true即可。

如圖

如何實踐Service Mesh微服務架構的基礎部署

payment、catalogueusersgolang項目,項目已在內(nèi)部集成了 zipkin 組件,我們需要添加環(huán)境變量ZIPKINhttp://zipkin:9411/api/v1/spans 來明確服務調(diào)用 zipkin 的地址。

如圖

如何實踐Service Mesh微服務架構的基礎部署

設置完成后,可以做直接訪問 zipkin 應用對外提供的訪問地址。訪問詳情如圖

如何實踐Service Mesh微服務架構的基礎部署

我們可以在該圖中查看各個服務調(diào)用的延時詳情。

至此,我們已經(jīng)完成了基礎部署,可以看到完整的業(yè)務拓撲圖,sockshop也已經(jīng)可以正常工作了。

關于如何實踐Service Mesh微服務架構的基礎部署就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI