服务注册与发现

本文主要内容:

  • 服务注册与发现的作用
  • 准备工作
  • 服务注册
  • 服务发现
  • 客户端发现服务
  • 服务注册与发现工作原理
  • 附源码

服务注册与发现作用

  • 服务注册:服务进程在注册中心注册自己的位置。它通常注册自己的主机和端口号,有时还有身份验证信息,协议,版本号,以及运行环境的详细资料。

  • 服务发现:客户端应用进程向注册中心发起查询,来获取服务的位置。服务发现的一个重要作用就是提供一个可用的服务列表

准备工作

  • 下载 Consul 镜像
    docker pull consul:0.9.2
  • 安装 consul-template
    brew install consul-template
  • 安装 nginx
    brew install nginx
  • 启动 nginx
    brew services restart nginx
  • 启动 Consul
    docker run -d -p 8500:8500 -p 8300:8300 -p 8301:8301 -p 8302:8302 -p 8600:8600 consul:0.9.2 agent -dev -bind=0.0.0.0 -client=0.0.0.0
  • 点击此处查看 Consul 服务

服务注册

  • 在 build.gradle 中加入依赖
ext {
     springCloudVersion = 'Dalston.SR4'
}
 dependencyManagement {
     imports {
         mavenBom "org.springframework.cloud:spring-cloud-starter-parent:${springCl
 oudVersion}"
    }
}
 dependencies {
     ...
     compile('org.springframework.boot:spring-boot-starter-actuator')
     compile('org.springframework.cloud:spring-cloud-starter-consul-discovery')
     ...
}
  • bootstrap.yml 中加入配置
  spring:
   cloud:
     consul:
       enabled: true
       hostname: localhost
       port: 8500
       ribbon:
         enabled: true
       discovery:
         enabled: true
         register: true
  • 在项目的入口加入注解
@SpringBootApplication
@EnableDiscoveryClient  //加入此注解
 public class MstUserServiceApplication {
     public static void main(String[] args) {
         SpringApplication.run(MstUserServiceApplication.class, args);
  } 
}

到此,我们的服务已经注册成功,点击此处查看服务注册,结果如下图:

红色选中区域就是我们注册的服务 mst-user-service,此时我们注册的服务是失败的,由于健康检查没过

  • 健康检查
    WebSecurityConfig.java 中加入:
http.authorizeRequests()
            .antMatchers(HttpMethod.GET, "/health").permitAll()
            .anyRequest().authenticated();

重启 mst-user-service 服务,再次点击此处查看服务注册,结果如下图:

至此,我们 mst-user-service 服务已经注册成功。接下来,服务发现。

服务发现

按照上述服务注册的方式,将该服务先用 consul 注册

  • 在发现方 build.gradle 中加入依赖
dependencies {
     ...
     compile('org.springframework.cloud:spring-cloud-starter-feign')
     ... 
}
  • 在发现方入口加入注解
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients  // 加入此注解
 public class MstOrderServiceApplication {
     public static void main(String[] args) {
         SpringApplication.run(MstOrderServiceApplication.class, args);
    } 
}
  • 创建 UserClient 接口,并在发现方写一个跨服务调用的接口
@FeignClient("mst-user-service")  // 此处名字应与我们在 Consul 中注册的名字一致
 public interface UserClient {
     @GetMapping("/api/users/names")
     List<String> getUserNames();
}
  • 重启发现方服务,发送请求。

客户端发现服务——Consul Template + Nginx

  • 设置 Consul Template
    mkdir consule-template && cd consule-template

  • 生成 Consul Template Config 文件

cat >> ./config.json << EOF
 {
   "consul": {
     "address": "http://127.0.0.1:8500"
   },
   "template": {
     "source": "./config.ctmpl",
     "destination": "/usr/local/etc/nginx/servers/ms-nginx.conf",
     "command": "brew services reload nginx"
  }
}
EOF
  • 生成 Nginx 模板
{{range services}} {{$name := .Name}} {{$service := service .Name}}
 upstream {{$name}} {
   #zone upstream-{{$name}} 64k;
   {{range $service}}server {{.Address}}:{{.Port}} max_fails=3 fail_timeout=60 weight=1;
   {{else}}server 127.0.0.1:65535; # force a 502{{end}}
 } {{end}}
 server {
   listen 8999 default_server;
 {{range services}} {{$name := .Name}}
   location ~* {{ $name }} {
     proxy_pass http://{{$name}};
   }
{{end}}
   location / {
     root /usr/share/nginx/html/;
     index index.html;
} }
EOF
  • 启动 Consul Template
    consul-template -config ./config.json

  • 查看生成好的 nginx 模板
    vim /usr/local/etc/nginx/servers/ms-nginx.conf

  • Consul 中添加 Key/Value
    matchers/mst-users-service -> /api/(users)
    matchers/mst-order-service -> /api/(goods)
    点此查看 Consule Key/Value

  • 修改 config.ctmpl
    使用下面的代码,替换 config.ctmpl 中同位置的代码

  ...
 {{range services}} {{$name := .Name}}
   {{if (printf "matchers/%s" $name | keyExists)}}
   location ~* {{ printf "matchers/%s" $name | key }} {
     proxy_pass http://{{$name}};
   }
   {{end}}
 {{end}}
...
  • 重启 Consul Template

  • 查看生成好的 nginx 模板

此时,我们可以发请求到 Nginx 对应的 Port 来完成我们的跨服务调用。

服务注册与发现工作原理

  • 当 Service A 启动的时候,会向 Consul 发送一个 POST 请求,告诉 Consul 自己的 IP 和 Port。
  • Consul 接收到 Service A 的注册后,每隔 10s(默认)会向 Service A 发送一个健康检查的请求,检验 Service A 是否健康
  • 当 Service B 发送 GET 方式请求 /api/getA 到 Service A 时,会先从 Consul 中拿到一个存储服务 IP 和 Port 的临时表,从表中拿到 Service A 的 IP 和 Port 后再发送 GET 方式请求 /api/getA
  • 该临时表每隔 10s 会更新,只含有通过健康检查的 Service

附源码

mst-user-service
mst-order-service
consule-template

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容