全部产品
容器服务

集群内服务间路由和负载均衡

更新时间:2017-06-28 18:07:16   分享:   

在容器服务上可以通过 acsrouting 将基于域名的 HTTP 服务暴露出去,而且能够配合健康检查自动的负载均衡和服务发现,当其中一个容器出现问题之后,routing 会自动将健康检查失败的容器从后端摘除,所以能做到自动的服务发现。

然而这个例子是将服务暴露到外网,那么服务间如何通过这种方式做到自动的服务发现和负载均衡呢?容器服务引入了负载均衡功能,您只需要使用以 .local 结尾的域名,并在依赖的服务的 external_links 中增加这个域名, 依赖的服务便可以通过 .local 的域名访问到依赖的服务,并且能够配合健康检查做到自动的服务发现。

实现原理

  1. 利用了 Docker 1.10 之后支持在容器中做别名的方式,在依赖负载于 restserver.local 的服务的容器中 restserver.local 的域名解析到的是 routing 服务的地址,这样可以将 HTTP 请求转发到 routing 的容器,并带上 HOSTrestserver.local 的请求头。

  2. routing 会对配置了 aliyun.routing_port_xxx: restserver.local 的服务监听其容器的健康状态并挂载到 HAProxy 的后端,HAProxy 接收到带有 restserver.local HOST 头的 HTTP 请求就能转发到对应了容器了。

图

优势

  • 相对于使用 link 或者 hostname 的基于 DNS 的方式,首先不同客户端对 DNS 缓存的处理不一致会导致服务发现的延迟性,其次 DNS 的方案也只有 round robin,对于微服务的场景是不够用的。
  • 而相对于其他的微服务服务发现的解决方案,提供了一个实现无关的服务发现和负载均衡机制,无需 server 端和 client 应用做任何修改即可使用。
  • 服务生命周期是解耦的,每个微服务可以采用一个 docker-compose 模板独立部署,更新。相互之间只是通过一个虚拟域名实现动态绑定即可。

编排实例

  1. restserver: # 模拟 rest 服务
  2. image: nginx
  3. labels:
  4. aliyun.routing.port_80: restserver.local # 使用 local 的域名,只有集群内的容器可以访问这个域名
  5. aliyun.scale: "2" # 扩展出两个实例,模拟负载均衡
  6. aliyun.probe.url: "http://container:80" # 定义容器的健康检查策略是 http,端口是 80
  7. aliyun.probe.initial_delay_seconds: "2" # 健康检查在容器起来之后两秒之后再检查
  8. aliyun.probe.timeout_seconds: "2" # 健康检查超时时间,如果两秒还没返回认为不健康
  9. restclient: # 模拟 rest 服务消费者
  10. image: registry.aliyuncs.com/acs-sample/alpine:3.3
  11. command: "sh -c 'apk update; apk add curl; while true; do curl --head restserver.local; sleep 1; done'" #访问 rest 服务,测试负载均衡
  12. tty: true
  13. external_links:
  14. - "restserver.local" #指定 link 的服务的域名。请确保您设置了 external_links,否则访问会失败。

然后,通过如下的 restclient 服务的日志,您可以看到 restclient 的 curl 的 http 请求被路由到不同的 rest 服务的容器上了,容器 ID 分别为 053cb232fdfbcb5405ff791650a0746ab77f26cce74fea2320075c2af55c975fb8c36abca525ac7fb02d2a9fcaba8d36641447a774ea956cd93068419f17ee3f

  1. internal-loadbalance_restclient_1 | 2016-07-01T06:43:49.066803626Z Server: nginx/1.11.1
  2. internal-loadbalance_restclient_1 | 2016-07-01T06:43:49.066814507Z Date: Fri, 01 Jul 2016 06:43:49 GMT
  3. internal-loadbalance_restclient_1 | 2016-07-01T06:43:49.066821392Z Content-Type: text/html
  4. internal-loadbalance_restclient_1 | 2016-07-01T06:43:49.066829291Z Content-Length: 612
  5. internal-loadbalance_restclient_1 | 2016-07-01T06:43:49.066835259Z Last-Modified: Tue, 31 May 2016 14:40:22 GMT
  6. internal-loadbalance_restclient_1 | 2016-07-01T06:43:49.066841201Z ETag: "574da256-264"
  7. internal-loadbalance_restclient_1 | 2016-07-01T06:43:49.066847245Z Accept-Ranges: bytes
  8. internal-loadbalance_restclient_1 | 2016-07-01T06:43:49.066853137Z Set-Cookie: CONTAINERID=053cb232fdfbcb5405ff791650a0746ab77f26cce74fea2320075c2af55c975f; path=/
  9. internal-loadbalance_restclient_1 | 2016-07-01T06:43:50.080502413Z HTTP/1.1 200 OK
  10. internal-loadbalance_restclient_1 | 2016-07-01T06:43:50.082548154Z Server: nginx/1.11.1
  11. internal-loadbalance_restclient_1 | 2016-07-01T06:43:50.082559109Z Date: Fri, 01 Jul 2016 06:43:50 GMT
  12. internal-loadbalance_restclient_1 | 2016-07-01T06:43:50.082589299Z Content-Type: text/html
  13. internal-loadbalance_restclient_1 | 2016-07-01T06:43:50.082596541Z Content-Length: 612
  14. internal-loadbalance_restclient_1 | 2016-07-01T06:43:50.082602580Z Last-Modified: Tue, 31 May 2016 14:40:22 GMT
  15. internal-loadbalance_restclient_1 | 2016-07-01T06:43:50.082608807Z ETag: "574da256-264"
  16. internal-loadbalance_restclient_1 | 2016-07-01T06:43:50.082614780Z Accept-Ranges: bytes
  17. internal-loadbalance_restclient_1 | 2016-07-01T06:43:50.082621152Z Set-Cookie: CONTAINERID=b8c36abca525ac7fb02d2a9fcaba8d36641447a774ea956cd93068419f17ee3f; path=/

本文导读目录
本文导读目录
以上内容是否对您有帮助?