《云计算与虚拟化技术丛书 Service Mesh实战》—3.2.5部署示例服务
3.2.5 部署示例服务
演示环境中我们将部署UserService、BookingService、ConcertService和MySQL数据库,Linkerd作为它们之间的Service Mesh层,以此进行演示及讲解Linkerd配置。假定UserService和MySQL各1个实例,运行在linkerd01,BookingService和ConcertService各1实例,运行在linkerd02和linkerd03,示例环境中我们通过脚本启动相应服务,所需脚本存放于每台虚机的/vagrant目录,每台虚机上需要启动哪些服务可参考下面表格所述。
launchMysql.sh:启动MySQL,需要首先启动,其他服务依赖MySQL。
launchUser.sh:启动UserService。
launchBooking.sh:启动BookingService。
launchConcert.sh:启动ConcertService。
initialize.sh:创建用户信息、演唱会信息以及预定演唱会,在其他服务成功启动后执行即可。
provision.sh:无需直接执行该脚本,只用于启动虚拟机时安装相关依赖软件。
其中initialize.sh内容如:
#!/bin/bash
# 调用user服务API创建用户信息并返回
user_id=$(/bin/curl \
-s \
-X POST \
-H "Host: user.service.consul" \
-d '{"ID": "tom","Name": "Tom Gao","Age": 23}' \
localhost:4140/users | jq -r '.id')
# 调用concert服务API创建演唱会信息并返回concert ID用作预定使用
concert_id=$(/bin/curl \
-s \
-X POST \
-H "Host: concert.service.consul" \
-d '{"concert_name": "The best of Andy Lau 2018","singer": "Andy Lau","start_date": "2018-03-27 20:30:00","end_date": "2018-04-07 23:00:00","location": "Shanghai", "street": "Jiangwan Stadium"}' \
localhost:4140/concerts | jq -r '.id')
# 调用booking服务API预定演唱会
/bin/curl \
-s \
-X POST \
-H "Host: booking.service.consul" \
-d @<(cat <<EOF
{
"user_id": "${user_id}",
"date": "2018-04-02 20:30:00",
"concert_id": "${concert_id}"
}
EOF
) \
localhost:4140/bookings >/dev/null
注意 本章演示所使用示例服务Docker镜像版本号为1.0
每个服务启动脚本定义启动服务所需的配置、启动命令以及如何将服务注册到Registrator,比如脚本launchUser.sh中,由于UserService需要访问BookingService和ConcertService,其配置信息为:
BOOKING_SERVICE_ADDR=booking.service.consul
CONCERT_SERVICE_ADDR=concert.service.consul
对每个不同的服务,更多具体配置信息可参考对应的启动脚本。
另外,需要注意的是服务启动脚本中启动服务容器时须注入环境变量http_proxy=localhost:4140使Linkerd作为HTTP proxy,这样所有HTTP请求都将发送给Linkerd,而不是直接发给真实目标服务实例,以此获取Linkerd提供的各种功能。
最后,表3-1描述在每台机器上将启动哪些服务以及相应数量信息。
表3-1 示例应用资源
现启动相应服务并初始化演示环境:
# bash launchMysql.sh
# bash launchUser.sh
# bash launchBooking.sh
# bash launchConcert.sh
# 初始化演示环境信息
# bash initialize.sh
完成服务启动后,可查询服务是否已注册到Consul,通过Consul API即可实现:
# curl -s localhost:8500/v1/catalog/services | jq
{
"booking": [],
"concert": [],
"consul": [],
"mysql": [],
"user": []
}
当然也可查看单个服务的注册信息,比如user:
# curl -s localhost:8500/v1/catalog/service/user | jq
[
{
"ID": "980daa76-5bd2-7a57-4750-9d20520efa1d",
"Node": "linkerd01",
"Address": "192.168.1.11",
"Datacenter": "dc1",
"TaggedAddresses": {
"lan": "192.168.1.11",
"wan": "192.168.1.11"
},
"NodeMeta": {
"consul-network-segment": ""
},
"ServiceID": "linkerd01:user-af729823bc:62000",
"ServiceName": "user",
"ServiceTags": [],
"ServiceAddress": "",
"ServicePort": 62000,
"ServiceEnableTagOverride": false,
"CreateIndex": 839,
"ModifyIndex": 839
}
]
返回结果告知服务所在Consul数据中心、IP地址、端口等信息。
在完成initialize.sh之后,用户信息、演唱会信息以及预定演唱会都已写入到MySQL,因此我们可以通过API获取相应信息,比如通过UserService服务的接口GET /users/{user_id}/bookings查询用户tom所预定演唱会及演唱会详细信息:
# curl -s http://192.168.1.11:62000/users/tom/bookings | jq
{
"tom": [
{
"date": "2018-04-02 20:30:00",
"concert_name": "The best of Andy Lau 2018",
"singer": "Andy Lau",
"location": "Shanghai"
}
]
}
注意 UserService的端口62000,启动服务时随机产生,不同环境可能不一样,但可从Consul中查询到。
当UserService通过booking.service.consul访问BookingService查询用户的所有预定以及通过concert.service.consul访问ConcertService查看预定对应演唱会的详细信息时,如前所述,我们在每个服务的容器中注入环境变量http_proxy=localhost:4140,这使得UserService访问BookingService和ConcertService都将流量转发到Linkerd,根据Linkerd的配置,然后Linkerd将流量转发到目标服务。因此执行上述查询时,它们之间的数据流如图3-4所示。
图3-4 示例应用访问数据流
如图3-4所示,具体过程如下。
客户端向UserService发起请求;
UserService将访问BookingService请求发送给本机Linkerd;
Linkerd通过配置的namer也就是Consul进行服务发现;
根据Linkerd的配置,把服务发现返回的地址经过Linkerd转换后,使用负载均衡算法把请求再次转发到目标Linkerd;
目标Linkerd接收请求后再次执行服务发现查找BookingService的地址;
Linkerd将再次把服务发现的BookingService地址进行转换,并执行负载均衡选取最优节点,请求被转发到该最优节点。
- 点赞
- 收藏
- 关注作者
评论(0)