服务网格实践之servicecomb-mesher


作者 | chen shuo

一、service mesh(服务网格)

1、 service mesh诞生背景

自从微服务和云计算兴起后,诞生了无数优秀的微服务架构,给开发部署带来了巨大的便利,敏捷开发获得了最佳的实践场景。然而微服务模式带来便利和高性能的同时不可避免会带来服务数量的膨胀,处理链路复杂化,底层架构和微服务框架差异化,因此服务治理问题成为了新的痛点,为了解决以上场景,service mesh 概念诞生。

service mesh (服务网格)通过在微服务网络中加入一些与业务服务解耦的服务实例,充当消息转发的角色,本质是在应用层加入一个通信管理层来管理网络中微服务的服务互通、服务发现、服务治理、链路追踪、健康监控等问题。使用服务网格后,在业务层面基本不用改动的情况下,以前复杂系统中需要考虑的跨团队服务设计,语言选择,异架构通信,链路管理,服务治理,服务上云等难题都能在一个统一的基础设施框架中得到解决。

那么具体是怎么做到的呢?服务网格通过增加一个代理服务,与原有微服务并行跑在一个基础设施上,这里的基础设施可以是物理机或者容器。这个代理服务主要有两个功能:

(1) 请求代理,所有原本直接发给微服务的请求都会被代理实例拦截,代理程序再将请求转发给真正的微服务处理,原有微服务发起的所有请求也将先转发给这个代理,由代理向外部的微服务网络发起请求。

(2) 组成可见的微服务网络节点,这个代理需要通过某种方式向微服务网络世界暴露自己,比如向某个分布式服务中心注册,代表业务服务实例参与到服务网络中,执行复杂的服务治理策略、调用链追踪、路由控制等功能。

下图中的 proxy 代表服务网格实例,server 代表微服务实例,这是服务网格的主要模式 sidecar,可以看到,每个微服务实例都有单独的服务网格实例为它服务,可以理解为在车道上并排奔跑的两个微服务,server 处理业务请求,负责业务层面的工作,proxy 服务拦截进出 server 的流量,负责微服务通信和治理层面的问题。

本文主要结合 Apache 项目 servicecomb-mesher 来介绍服务网格的实现,其他项目不做展开介绍。

01.png


图1 服务网格鸟瞰图

二、servicecomb-mesher

Servicecomb-mesher 是 Apache servicecomb 的服务网格项目。使用 go 语言基于 go-chassis 开源框架实现,go-chassis 框架以插件的形式支持负载均衡、流量控制、调用链追踪、熔断降级、服务治理、动态配置管理等微服务能力。mesher目前支持sidecar和edgeservice两种运行模式。支持服务间使用http、grpc协议通信,有良好的可扩展性,用户可自行扩展自己的协议。mesher以调用链的形式处理请求,可以根据配置自由裁剪处理函数。在控制面mesher天然能够接入apache servicecomb微服务体系。并对当前主流的service-mesh具有兼容性,支持kubernetes,可接入Istio。

02.png


图2 mesher交互模型图

2.1 Servicecomb-mesher原理浅析

我们以 sidecar 模式运行 mesher,通过一个具体的 http 协议通信为例介绍 mesher 做了什么工作。

(1) 我们启动一个真正的 http server 作为业务服务,这里对 http server 的实现语言,服务框架没有任何限制;

(2) 启动 mesher,mesher会根据配置信息启动两个 http 服务,分别监听在本地回环和本地 ip 上(如127.0.0.1:30101 和 192.168.88.64:30101)。mesher 通过127.0.0.1:30101 处理内部业务服务对外部的请求流量;监听在 192.168.88.64:30101 的服务用于处理外部对内部业务服务的请求流量;

(3) 如图,client 作为一个请求发起方,client 的请求通过代理转发到与它绑定的 mesher(127.0.0.1:30102);

(4) mesher(127.0.0.1:30102)接收到请求后,使用 LocalRequestHandler 处理请求,首先准备 consumer 调用链,获取并解析 client 调用的服务名和端口,创建 Invocation,之后通过 consumer 调用链进行处理,最后建立一个 rest-client 对外部的目的服务(192.168.88.64:30101)发起调用;

(5) 监听在 192.168.88.64:30101 的 mesher 接收到请求后,调用 RemoteRequestHandler 处理请求,首先将请求转为 Invocation,准备 provider 调用链,解析地址,将目的地址替换为业务服务的地址,然后调用处理链处理请求,最终向内部真正的业务 server 发起 http 调用;

监听在 127.0.0.1:30101 的 mesher 作为 consumer,使用处理请求,consumerChain 调用链默认包含如下处理器(handler):
  • chassisHandler.Router,chassisHandler.RatelimiterConsumer
  • chassisHandler.BizkeeperConsumer
  • chassisHandler.Loadbalance
  • chassisHandler.Transport


监听在 192.168.88.64:30101 的 mesher 作为 provider 处理请求,providerChain 调用链默认包含如下处理器(handler):
  • chassisHandler.RatelimiterProvider
  • chassisHandler.Transport


03.png


图3 mesher通信模型图

通过以上分析可以看到,mesher 实际上在应用层作为一个代理,拦截并代替业务服务发起和接收请求,mesher 和业务服务各司其职,业务服务只要保证业务功能正常,mesher 负责服务治理层面,构建可靠的通信链路。我们只要保证 mesher 与业务的互通以及 mesher 与外部其他 mesher 之间的通信就可以保证提供服务,那么这里 mesher 是如何做到的呢?这个问题就涉及到 go-chassis 开源框架的服务发现和控制面管理功能。mesher 使用 go-chassis 底座的 register 包将自己注册到服务中心实例,这里我们使用 Apache 的 servicecomb-servicecenter,它是一个接收微服务注册并进行管理的服务中心,所有连接到 servicecenter 的服务都可以通过服务中心向其他服务暴露自己,并通过微服务名获取到其他服务实例的 ip 和 port。mesher 的控制面功能支持断路器、负载均衡、频率限制、错误注入等,可以接入istio或者使用archaius以读取配置的方式。

三、体质指数(Bmi)入门案例

3.1 背景

了解了 mesher 的原理后,我们通过一个具体的用例帮助用户快速入门 mesher 的 sidecar 模式。希望帮助用户通过该例子,能够快速上手使用 mesher 服务,深入了解 mesher 的工作模式和原理,并掌握如何通过 mesher 的帮助改造已有的 http 服务,接入 servicecomb 微服务体系,获得负载均衡、流控、服务治理、调用链追踪等微服务能力。具体案例配置和代码可以通过 github 下载:

https://github.com/apache/serv ... start

3.2 用例服务介绍

04.png


图4 mesher案例部署图

1、httpserver_calculator:基于python语言实现的http体质指数服务,可替换为任何语言开发的http服务;

2、httpserver_webapp:基于 nodejs 语言实现的web服务,用于在浏览器上展示可视化结果;

3、mesher_webapp:通过 sidecar 模式为httpserver_webapp 提供服务的 mesher 实例;

4、mesher_calculator:通过 sidecar 模式为httpserver_calculator 提供服务的 mesher 实例;

5、servicecenter:服务中心,接收 mesher 服务的注册,提供服务发现、路由查询、服务监控功能;

流程详情:

浏览器[192.168.88.78]对 httpserver_webapp 服务发起 http 调用 http://192.168.88.64:4597/calculator/bmi
httpserver_webapp 服务接收请求,并发起对地址 http://calculator/bmi 的 http 调用,因为设置了代理http://127.0.0.1:30101,httpserver_webapp 发起的请求将被转发到 mesher_webapp 服务。
mesher_webapp 根据请求的服务名(microservice.yaml 配置的服务名 calculator)从服务中心 servicecenter 获得该服务名的地址,转发到 mesher_calculator。
mesher_calculator 服务根据设置好的specific地址,转发到自己绑定的体质指数calculator服务(httpserver_calculator)进行处理。
httpserver_calculator 会根据用户身高和体重进行计算,并返回自己的服务标识展示在界面上。流程图如下所示:

05.png


图5 mesher案例流程图

3.4 测试环境搭建(linux)

1、编译 mesher :下载地址

按README.md编译项目得到可执行文件mesher(linux),windows(mesher.exe);

2、创建 mesher_webapp 用于为 httpserver_webapp 服务:

在 mesher 目录下执行下列linux命令创建 mesher_webapp,此处除了可执行文件,还需要拷贝conf
mkdir /usr/local/src/mesher_webapp
cp ./mesher /usr/local/src/mesher_webapp
cp -r ./conf /usr/local/src/mesher_webapp


更改 conf 中配置文件,microservice.yaml 中的服务 name,从 hellomesher 改为 webapp;更改 chassis.yaml 中监听的服务地址,从本地回环(127.0.0.1)地址改为内网 ip(linux下通过 ifconfig 查看,如192.168.88.64):
listenAddress: 127.0.0.1:40101  ->  listenAddress: 192.168.88.64:40101
listenAddress: 127.0.0.1:30101  ->  listenAddress: 192.168.88.64:30101
listenAddress: 127.0.0.1:30102  ->  listenAddress: 192.168.88.64:30102 


3、创建mesher_calculator
mkdir /usr/local/src/mesher_calculator
cp ./mesher /usr/local/src/mesher_calculator
cp -r ./conf /usr/local/src/mesher_calculator


更改conf中配置文件,分别更改microservice.yaml中的服务name为体质指数微服务名calculator;
更改mesher_calculator配置chassis.yaml监听的地址和端口:
listenAddress: 127.0.0.1:40101  ->  listenAddress: 192.168.88.64:40107
listenAddress: 127.0.0.1:30101  ->  listenAddress: 192.168.88.64:30111
listenAddress: 127.0.0.1:30102  ->  listenAddress: 192.168.88.64:30112


4、 启动mesher服务,分别进入mesher_webapp和mesher_calculator,启动服务,其中需要设置mesher_calculator的SPECIFIC_ADDR地址,该地址用于建立mesher和http服务逻辑上的绑定关系;
cd /usr/local/src/mesher_calculator
export SPECIFIC_ADDR=127.0.0.1:4540
./mesher
cd /usr/local/src/mesher_webapp
./mesher


5、 启动httpserver_webapp服务:
cd /usr/local/src/httpserver_webapp
node ./httpserver_webapp.js


6、 httpserver_calculator 作为体质指数计算服务,需要安装python2.7,依赖BaseHTTPServer包:
cd /usr/local/src/httpserver_calculator
./httpserver_calculator.py


06.png


图6 servicecenter服务监控图

3.5 测试

1、浏览器打开页面 http://192.168.88.64:30103 (如果打不开需要开启服务中心 service-center 的 front 服务,参考http://servicecomb.apache.org/ ... t/%23运行service-center

查看服务,其中地址 service-center 服务启动的地址,看到如图界面。

webapp 代表 mesher_webapp 服务,这里展示的是 microservice.yaml 中配置的服务名;calculator 代表 mesher_calculator 服务,这里展示的是 microservice.yaml 中配置的服务名。大写的 SERVICECENTER 是服务中心。

07.png


图7 servicecenter服务监控图

2、浏览器打开 http://192.168.88.64:4597,可以看到如下界面,为 webapp 呈现的静态页面:

08.png


图8 bmi调用结果展示界面图

3、输入参数(180、70)点击 submit,观察结果:

09.png


图9 bmi调用结果图

3.6 mesher进阶

3.6.1 负载均衡

10.png


图10 mesher 负载均衡案例部署图

启动一个新的 mesher_calculator 和 httpserver_calculator 实例用于负载均衡测试,可以使用例子目录test_balance下的服务:

1、修改 mesher_calculator 配置文件 microservice.yaml 中的服务 name 为 calculator;
更改配置 chassis.yaml 监听的地址和端口避免冲突:
listenAddress: 127.0.0.1:40101  ->  listenAddress: 192.168.88.64:40102
listenAddress: 127.0.0.1:30101  ->  listenAddress: 192.168.88.64:30108
listenAddress: 127.0.0.1:30102  ->  listenAddress: 192.168.88.64:30109


2、启动 mesher_calculator,需要设置 mesher_calculator 的 SPECIFIC_ADDR 地址,该地址用于建立 mesher 和 http 服务逻辑上的绑定关系;
export SPECIFIC_ADDR=127.0.0.1:4537
./mesher


3、默认情况下会使用 roundbin(轮询)负载均衡算法,另外还支持 Random 和 SessionStickiness 负载均衡算法。我们修改 mesher_webapp 的配置文件 chassis.yaml,将负载均衡方法配置为 Random:
loadbalance:
strategy:
name: Random


4、开启 httpserver_calculator 服务新实例,监听4537端口。

5、此时点击 Submit 按钮就可以看到如下两个界面中的 BMI Instance ID 随机出现;

11.png


图11 bmi调用结果图

1101.png


图11 bmi调用结果图

2.6.2 流量控制
1、添加流量控制配置,重启服务,更改 mesher_calculator配置文件 chassis.yaml,其中流量控制包含下列选项:
flowcontrol:
Provider:
  qps:
    enabled: true
    global:
      limit: 100    
      Server: 100


该频率限制标识每秒接受的请求为0,即不提供服务。

2、验证,点击 Submit 按钮,此时能看到由于流控受限而请求被拒的界面,请求已经无法到达 httpserver_calculator。

13.png


图13 流量控制展示图

1301.png


图13 流量控制展示图

3.6.3 服务治理

3.6.3.1 灰度发布

1、更新版本号:分别更改两个 mesher_calculator 实例的配置文件 microservice.yaml,更新 version 字段分别为1.1.1和1.1.2,重启 mesher 服务,可以看到服务版本号发生了变更。如图中所示:

14.png


图14 服务监控图

2、配置路由信息,更改 mesher_webapp 的配置文件 router.yaml,按实例版本更新权重信息,并重启服务:
servicecomb:
routeRule:
  calculator: | # 服务名
    - precedence: 1 # 优先级
      route: #路由规则
        - weight: 70 #权重值          
          tags:            
            version: 1.1.1
        - weight: 30 #权重值          
          tags:            
            version: 1.1.2


3、验证,此时大量点击 Submit 按钮就可以看到 BMI Instance ID 按配置的比例交替出现。

3.6.3.2 服务熔断及恢复

1、更改断流器配置,更改 mesher_webapp 的配置文件 chassis.yaml,设置其中的断流器配置为:
isolation:
Consumer:
timeout:
  enabled: true
timeoutInMilliseconds: 1000            #超时时间
maxConcurrentRequests: 1
circuitBreaker:
Consumer:
enabled: true
forceOpen: false
forceClosed: false
sleepWindowInMilliseconds: 10000    #熔断恢复时间10秒
requestVolumeThreshold: 1          #请求量限制
errorThresholdPercentage: 1
fallback:
Consumer:
enabled: true
maxConcurrentRequests: 1
fallbackpolicy:
Consumer:
policy: returnnull


2、关闭 test_balance 目录下的服务实例。

3、验证,传入负数参数,响应超时,mesher_webapp 断流器生效,图16中三个子图分别是:

(1) mesher_webapp 日志截图,表明断流器启用。

(2) 传入负数参数触发断流器时的返回值。

(3) 表示断流器生效后对所有请求都按配置返回 nil。

16.jpg


1601.png


1602.png


图16 服务熔断展示图

4、根据配置参数 sleepWindowInMilliseconds,过10秒后服务自动恢复。

2.6.4 分布式调用链追踪
1、mesher main 文件中添加对zipkin库依赖:
_ "github.com/go-chassis/go-chassis-plugins/tracing/zipkin"


2、启发器 bootstrap.go 中添加默认处理函数,如图17中箭头所示:

17.png


图17 handlerchain调用图

3、重新编译,分别替换 mesher_webapp 和 mesher_calculator 的可执行文件,启动 mesher 服务。

4、 使用 Docker 运行 Zipkin 分布式追踪服务,链接:

http://servicecomb.apache.org/ ... cing/
docker run -d -p 9411:9411 openzipkin/zipkin


5、多次点击 Submit 按钮发起服务调用。

6、打开 http://192.168.88.64:9411 可查看分布式追踪结果如图18,可以通过 host 地址判断调用路径:

18.png


图18 分布式追踪结果图

长按扫码关注我们

一起为微服务技术添砖盖瓦~

0 个评论

要回复文章请先登录注册