Service-Center(SC)是一个服务注册中心。 服务提供者(provider)可以将自身的实例信息注册到 SC,以供服务消费者(consumer)从 SC 发现并使用它。
在传统服务中,一般将 provider 的实例信息配置到指定的配置文件中,以供 consumer 使用。这种使用方式下,若 provider 修改了配置信息,counsumer 则需要手工修改配置,并重启服务来适应变化。若是需要维护的服务较少,这倒不会花费太多气力。然而在微服务领域,涉及的服务数动辄成百上千,若是通过手工去维护这些配置,相信运维人员早就磨刀霍霍向开发了。服务注册中心应运而生。
参见:ServiceComb官网 ServiceCenter用户手册,此处不再赘述
官网获取指定版本并下载:http://servicecomb.apache.org/cn/release/
笔者在此处使用了 apache-servicecomb-incubating-service-center-1.0.0-linux-amd64.tar.gz 包,实际操作时请根据系统环境选取对应版本
# 下载linux版本包
$ wget http://archive.apache.org/dist/incubator/servicecomb/incubator-servicecomb-service-center/1.0.0/apache-servicecomb-incubating-service-center-1.0.0-linux-amd64.tar.gz
# 解压tar包
$ tar -zxvf apache-servicecomb-incubating-service-center-1.0.0-linux-amd64.tar.gz
# 启动servicecenter服务
$ cd apache-servicecomb-incubating-service-center-1.0.0-linux-amd64/
$ ./start-service-center.sh
$ ps -ef | grep service-center
root 27048 1 2 14:38 pts/2 00:00:00 ./service-center
root 27164 22742 0 14:38 pts/2 00:00:00 grep --color=auto service-center
# 查看监听配置
$ cat conf/app.conf | grep "sever options" -A 16
# sever options
###################################################################
# if you want to listen at ipv6 address, then set the httpaddr value like:
# httpaddr = 2400:A480:AAAA:200::159 (global scope)
# httpaddr = fe80::f816:3eff:fe17:c38b%eth0 (link-local scope)
httpaddr = 127.0.0.1
httpport = 30100
read_header_timeout = 60s
read_timeout = 60s
idle_timeout = 60s
write_timeout = 60s
max_header_bytes = 32768 # 32K
max_body_bytes = 2097152 # 2M
enable_pprof = 0
# 查看端口监听
$ netstat -apn | grep :30100
tcp 0 0 127.0.0.1:30100 0.0.0.0:* LISTEN 27048/service-cente
$ curl http://127.0.0.1:30100
{"_links":{"pb:latest-pact-versions":{"href":"http://127.0.0.1:30100/pacts/latest","title":"Latest pact versions"},"pb:latest-provider-pacts":{"href":"http://127.0.0.1:30100/pacts/provider/{provider}/latest","title":"Latest pacts by provider","templated":true},"pb:latest-provider-pacts-with-tag":{"href":"http://127.0.0.1:30100/pacts/provider/{provider}/latest/{tag}","title":"Latest pacts by provider with a specified tag","templated":true},"pb:pacticipants":{"href":"http://127.0.0.1:30100/participants","title":"Pacticipants"},"pb:publish-pact":{"href":"http://127.0.0.1:30100/pacts/provider/{provider}/consumer/{consumer}/version/{consumerApplicationVersion}","title":"Publish a pact","templated":true},"pb:webhooks":{"href":"http://127.0.0.1:30100/webhooks","title":"Webhooks"},"self":{"href":"http://127.0.0.1:30100/","title":"Index"}},"curies":[{"href":"http://127.0.0.1:30100/doc/{rel}","name":"pb"}]}
至此,service-center服务已成功启动,其监听地址为: 127.0.0.1:30100
gihub官方代码库:https://github.com/apache/servicecomb-service-center
注:源码安装时涉及 golang.org/x/… 等包的下载,若因"墙"无法下载的,可以通过设置 goproxy解决
goproxy 设置:
$ echo "export GOPROXY=https://goproxy.io" >> /etc/profile
$ source /etc/profile
安装启动:
# 源码下载
$ git clone https://github.com/apache/servicecomb-service-center.git $GOPATH/src/github.com/apache/servicecomb-service-center
Cloning into '/root/chan/go//src/github.com/apache/servicecomb-service-center'...
remote: Enumerating objects: 224, done.
remote: Counting objects: 100% (224/224), done.
remote: Compressing objects: 100% (155/155), done.
remote: Total 18042 (delta 111), reused 120 (delta 66), pack-reused 17818
Receiving objects: 100% (18042/18042), 16.05 MiB | 1.51 MiB/s, done.
Resolving deltas: 100% (9863/9863), done.
Checking connectivity... done.
$ cd $GOPATH/src/github.com/apache/servicecomb-service-center
# 查看并确保 go 版本到 1.11+
$ go version
go version go1.11.4 linux/amd64
# 源码编译
$ GO111MODULE=on go mod download
go: finding github.com/dgrijalva/jwt-go v3.2.0+incompatible
go: finding github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea
...
go: finding k8s.io/client-go v2.0.0-alpha.0.0.20180817174322-745ca8300397+incompatible
$ GO111MODULE=on go mod vendor
$ go build -o service-center
# 安装并启动 etcd
$ wget https://github.com/coreos/etcd/releases/download/v3.1.8/etcd-v3.1.8-linux-amd64.tar.gz
$ tar -xvf etcd-v3.1.8-linux-amd64.tar.gz
$ cd etcd-v3.1.8-linux-amd64
$ ./etcd
# 配置并启动 service-center
$ cd $GOPATH/src/github.com/apache/servicecomb-service-center
$ cp -r ./etc/conf .
$ ./service-center
# 查看端口监听
$ cat conf/app.conf | grep "sever options" -A 16
# sever options
###################################################################
# if you want to listen at ipv6 address, then set the httpaddr value like:
# httpaddr = 2400:A480:AAAA:200::159 (global scope)
# httpaddr = fe80::f816:3eff:fe17:c38b%eth0 (link-local scope)
httpaddr = 127.0.0.1
httpport = 30100
read_header_timeout = 60s
read_timeout = 60s
idle_timeout = 60s
write_timeout = 60s
max_header_bytes = 32768 # 32K
max_body_bytes = 2097152 # 2M
enable_pprof = 0
此处将从 docker 和 kubernetes 两个方向,对service-center容器的启动进行介绍
由于文章仅做 service-center 研究,涉及 docker、kubernetes 知识还请各位自行补充
注:docker 拉取镜像时,若涉及国外镜像无法下载,可以通过设置 docker registry-mirror进行解决
docker registry-mirror 设置:
$ cat <<EOF > /etc/docker/daemon.json
{
"registry-mirrors": ["https://registry.docker-cn.com"]
}
EOF
$ sudo systemctl daemon-reload
$ sudo systemctl start docker
docker 镜像运行:
# 下载镜像
$ docker pull servicecomb/service-center
Using default tag: latest
latest: Pulling from servicecomb/service-center
Digest: sha256:d1c74d569dc4ca09649add02aab16758325a5b0945b0029bd70f446e6db112b4
Status: Downloaded newer image for servicecomb/service-center:latest
# 启动容器
$ docker run -d -p 30100:30100 servicecomb/service-center
0733021cd96d466f7eb27e482c9dbe75b980aad1bac0490e9b5ed65bd5329e0b
# 查看端口监听
$ docker ps | grep service-center
0733021cd96d servicecomb/service-center "/opt/service-cent..." 3 minutes ago Up 3 minutes 0.0.0.0:30100->30100/tcp gallant_varahamihira
$ curl http://127.0.0.1:30100
{"_links":{"pb:latest-pact-versions":{"href":"http://127.0.0.1:30100/pacts/latest","title":"Latest pact versions"},"pb:latest-provider-pacts":{"href":"http://127.0.0.1:30100/pacts/provider/{provider}/latest","title":"Latest pacts by provider","templated":true},"pb:latest-provider-pacts-with-tag":{"href":"http://127.0.0.1:30100/pacts/provider/{provider}/latest/{tag}","title":"Latest pacts by provider with a specified tag","templated":true},"pb:pacticipants":{"href":"http://127.0.0.1:30100/participants","title":"Pacticipants"},"pb:publish-pact":{"href":"http://127.0.0.1:30100/pacts/provider/{provider}/consumer/{consumer}/version/{consumerApplicationVersion}","title":"Publish a pact","templated":true},"pb:webhooks":{"href":"http://127.0.0.1:30100/webhooks","title":"Webhooks"},"self":{"href":"http://127.0.0.1:30100/","title":"Index"}},"curies":[{"href":"http://127.0.0.1:30100/doc/{rel}","name":"pb"}]}
容器已启动并监听 127.0.0.1:30100 成功
# 配置 kubernetes 资源文件
$ cat <<EOF >> ./service-center.yaml
apiVersion: v1
kind: Service
metadata:
name: servicecenter
labels:
app: servicecenter
spec:
ports:
- port: 30100
name: http
selector:
app: servicecenter
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: servicecenter
spec:
replicas: 1
template:
metadata:
labels:
app: servicecenter
version: v1
spec:
containers:
- name: servicecenter
image: servicecomb/service-center:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 30100
EOF
# 创建 namespace "servicecomb"
$ kubectl create namespace servicecomb
namespace/servicecomb created
# 部署 service-center
$ kubectl -n servicecomb create -f service-center.yaml
service/servicecenter created
deployment.extensions/servicecenter created
# 查看 pod 启动状态
$ kubectl -n servicecomb get pod
NAME READY STATUS RESTARTS AGE
servicecenter-7d964b7644-h6f4s 1/1 Running 0 72s
# 获取 service 监听
$ kubectl -n servicecomb get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
servicecenter ClusterIP 10.104.241.163 <none> 30100/TCP 118s
$ curl http://10.104.241.163:30100
{"_links":{"pb:latest-pact-versions":{"href":"http://10.104.241.163:30100/pacts/latest","title":"Latest pact versions"},"pb:latest-provider-pacts":{"href":"http://10.104.241.163:30100/pacts/provider/{provider}/latest","title":"Latest pacts by provider","templated":true},"pb:latest-provider-pacts-with-tag":{"href":"http://10.104.241.163:30100/pacts/provider/{provider}/latest/{tag}","title":"Latest pacts by provider with a specified tag","templated":true},"pb:pacticipants":{"href":"http://10.104.241.163:30100/participants","title":"Pacticipants"},"pb:publish-pact":{"href":"http://10.104.241.163:30100/pacts/provider/{provider}/consumer/{consumer}/version/{consumerApplicationVersion}","title":"Publish a pact","templated":true},"pb:webhooks":{"href":"http://10.104.241.163:30100/webhooks","title":"Webhooks"},"self":{"href":"http://10.104.241.163:30100/","title":"Index"}},"curies":[{"href":"http://10.104.241.163:30100/doc/{rel}","name":"pb"}]}
在 kubernetes 中部署 service-center 成功,其监听地址被分配到了 10.104.241.163:30100
以下将通过 curl 命令模拟 Service-center 中的服务注册与发现,以便于了解其流程。具体的示例与源码分析将在后续的文章中展现。
$ curl -X POST \
http://127.0.0.1:30100/registry/v3/microservices \
-H 'content-type: application/json' \
-H 'x-domain-name: default' \
-d '{
"service":
{
"appId": "default",
"serviceName": "ProviderDemoService",
"version":"1.0.0"
}
}'
{"serviceId":"fa82132706a6b75a13393d8cf48800f9689b2603"}
$ curl -X POST \
http://127.0.0.1:30100/registry/v3/microservices/fa82132706a6b75a13393d8cf48800f9689b2603/instances \
-H 'content-type: application/json' \
-H 'x-domain-name: default' \
-d '{
"instance":
{
"hostName":"provider-demo",
"endpoints": [
"rest://127.0.0.1:8080"
]
}
}'
{"instanceId":"6e160fb0196e11e9b8b50242ac110005"}
$ curl -X POST \
http://127.0.0.1:30100/registry/v3/microservices \
-H 'content-type: application/json' \
-H 'x-domain-name: default' \
-d '{
"service":
{
"appId": "default",
"serviceName": "ConsumerDemoService",
"version":"1.0.0"
}
}'
{"serviceId":"d08d29edbeaa372c5be88407aa9adb00b4cb6099"}
$ curl -X GET \
'http://127.0.0.1:30100/registry/v3/instances?appId=default&serviceName=ProviderDemoService&version=latest' \
-H 'content-type: application/json' \
-H 'x-consumerid: d08d29edbeaa372c5be88407aa9adb00b4cb6099' \
-H 'x-domain-name: default'
{
"instances": [
{
"instanceId": "c23da577197111e9b8b50242ac110005",
"serviceId": "fa82132706a6b75a13393d8cf48800f9689b2603",
"endpoints": [
"rest://127.0.0.1:8080"
],
"hostName": "provider-demo",
"status": "UP",
"healthCheck": {
"mode": "push",
"interval": 30,
"times": 3
},
"timestamp": "1547631199",
"modTimestamp": "1547631199",
"version": "1.0.0"
}
]
}
注:Provider 服务在 30 秒内未向 Service-Center 发送心跳,将会被下线。所以服务发现的请求应在 Provider 服务创建实例后 30 秒内发出才会成功发现实例