Spring Cloud 与 Consul
统一开头:
最近的工作安排中,需要把曾经庞大的、臃肿的综合管理“大平台”拆分,引入微服务的概念;找找看看一段时间仍然不晓得微服务到底是个啥。浅薄的认为就是一个个小的、功能相对单一的服务程序。
在不明白为何物的情况下怎么快速上手?搜罗了许多文章后找到了【纯洁的微笑】的博客,里面东西不老少。其中推荐了几个开源的软件,从中找到了《Cloud-Admin》。
在《Cloud-Admin》中,分别使用到RabbitMQ、Redis、MySQL 和 Consul 于是开始逐个攻克。
Consul简介
Consul 是 HashiCorp 公司推出的开源工具,用于实现分布式系统的服务发现与配置。与其它分布式服务注册与发现的方案,Consul 的方案更“一站式”,内置了服务注册与发现框 架、分布一致性协议实现、健康检查、Key/Value 存储、多数据中心方案,不再需要依赖其它工具(比如 ZooKeeper 等)。使用起来也较 为简单。Consul 使用 Go 语言编写,因此具有天然可移植性(支持Linux、windows和Mac OS X);安装包仅包含一个可执行文件,方便部署,与 Docker 等轻量级容器可无缝配合。
个人理解:Consul 是一个服务中心(注册中心),负责各个微服务之间的调用调度。有了新的供应服务到这里来注册一下;有消费端到这里来找找有没有需要的服务,有就拿去用。服务的注册、发现、熔断、负载、降级都在这里搞定。
Docker部署Consul
为了方便开发,在 Docker 上运行 Consul 容器来解决问题,通过docker search consul
可以看到在镜像库中已经有了Consul镜像,在【docker doc】中也有相关的说明。
首先把镜像拽下来docker pull consul
,拉取最新的版本,通过下面的命令创建并运行容器。
docker run -d --name springcloud-consul \
-p 8500:8500 -p 8600:8600 -p 8600:8600/udp \
consul
- -d: 后台运行
- --name springcloud-consul:指定容器的名字
- -p xxxx:xxxx/udp:绑定宿主机和容器的UDP协议端口
- -p xxxx:xxxx:绑定宿主机和容器的TCP协议端口
8300/8301/8302:Consul内部通信使用的端口,单个主机环境中这三个端口用不到;
8500:HTTP端口
8600:DNS端口
运行上述命令后,就已经在Docker中启动了一个Consul容器,打开浏览器输入http://127.0.0.1:8500/ui/
可以看到如下页面,证明Consul服务启动成功。
编写测试程序
测试程序参考了《springcloud(十三):注册中心 Consul 使用详解》文章。
开发工具:IntelliJ IDEA 2018.2.5
Java环境:1.8.0_162
SpringBoot版本:2.1.0.RELEASE
创建项目
今次首先在IDEA中创建一个空项目,之后再在其中创建3个Module,分别是一号供应商、二号供应商、需求方。
通过菜单在项目中创建“Module”
一号供应商
创建 Module 向导
项目的Artifact填写为producer1
(一号供应商),Next
;
在向导中依赖这里分别选择Web -> Web
、Cloud Discovery -> Consul Discovery
、Ops -> Actuator
;
- spring-boot-starter-actuator 健康检查依赖于此包。
- spring-cloud-starter-consul-discovery Spring Cloud Consul 的支持。
填写代码
Application主类中,添加注解@EnableDiscoveryClient
表示支持服务发现。
@SpringBootApplication
@EnableDiscoveryClient
public class Producer1Application {
public static void main(String[] args) {
SpringApplication.run(Producer1Application.class, args);
}
}
Spring Boot 配置文件中添加如下配置信息。
spring.application.name=spring-cloud-consul-producer1
server.port=8501
spring.cloud.consul.host=localhost
spring.cloud.consul.port=8500
#注册到consul的服务名称
spring.cloud.consul.discovery.serviceName=service-producer
创建一个Controller提供具体服务。
@RestController
public class HelloController {
@RequestMapping("/hello")
public String hello() {
return "Hello consul 1";
}
}
运行一号供应商的Spring Boot程序,启动服务;刷新“http://127.0.0.1:8500/ui/”页面,可以看到Services
里注册了一个service-producer
服务,并有两个节点(猜测一个是注册节点、一个是心跳检测节点)。
二号供应商
像一号供应商一样,如法炮制;不同的地方我们修改一下供应商的信息,把原先填“1”的地方都写“2”。
Spring Boot 配置文件中添加如下配置信息,注意端口号为8502
。
spring.application.name=spring-cloud-consul-producer2
server.port=8502
spring.cloud.consul.host=localhost
spring.cloud.consul.port=8500
#注册到consul的服务名称
spring.cloud.consul.discovery.serviceName=service-producer
同样创建一个Controller提供具体服务,这里返回的信息为“2”。
@RestController
public class HelloController {
@RequestMapping("/hello")
public String hello() {
return "Hello consul 2";
}
}
运行二号供应商的Spring Boot程序,启动服务;刷新“http://127.0.0.1:8500/ui/”页面,可以看到Services
里的service-producer
服务又多了两个节点。至此,两个供应商都报名成功。
需求方
创建 Module 向导
项目的Artifact填写为consumer
,Next
;
在向导中依赖这里分别选择Web -> Web
、Cloud Discovery -> Consul Discovery
;
填写代码
Application主类无需修改。
创建测试 Controller 类 ServiceController。
@RestController
public class ServiceController {
@Autowired
private LoadBalancerClient loadBalancer;
@Autowired
private DiscoveryClient discoveryClient;
/**
* 获取所有服务
*/
@RequestMapping("/services")
public Object services() {
return discoveryClient.getInstances("service-producer");
}
/**
* 从所有服务中选择一个服务(轮询)
*/
@RequestMapping("/discover")
public Object discover() {
return loadBalancer.choose("service-producer").getUri().toString();
}
/**
* 选择服务,享受供应商提供的服务(轮询)
*/
@RequestMapping("/call")
public String call() {
ServiceInstance serviceInstance = loadBalancer.choose("service-producer");
System.out.println("服务地址:" + serviceInstance.getUri());
System.out.println("服务名称:" + serviceInstance.getServiceId());
String callServiceResult = new RestTemplate().getForObject(serviceInstance.getUri().toString() + "/hello", String.class);
System.out.println(callServiceResult);
return callServiceResult;
}
}
Spring Boot 配置文件中添加如下配置信息。
spring.application.name=spring-cloud-consul-consumer
server.port=8503
spring.cloud.consul.host=localhost
spring.cloud.consul.port=8500
#设置不需要注册到 consul 中
spring.cloud.consul.discovery.register=false
spring.cloud.consul.discovery.instance-id=service-producer
项目结构
一号供应商与二号供应商接口类似,就不再展开。
运行测试
查看已注册的供应商
浏览器访问http://localhost:8503/services
返回如下信息,可以看到在服务中心注册了两个serviceId
为service-producer
的服务,并且可以看到地址、端口等信息。
[{
"serviceId": "service-producer",
"host": "aclyyxdeimac.lan",
"port": 8501,
"secure": false,
"metadata": { "secure": "false" },
"uri": "http://aclyyxdeimac.lan:8501",
"scheme": null
}, {
"serviceId": "service-producer",
"host": "aclyyxdeimac.lan",
"port": 8502,
"secure": false,
"metadata": { "secure": "false" },
"uri": "http://aclyyxdeimac.lan:8502",
"scheme": null
}]
选择一个供应商查看服务地址(轮询)
浏览器访问http://localhost:8503/discover
并反复刷新,返回如下两条信息交替显示。
http://aclyyxdeimac.lan:8501
或
http://aclyyxdeimac.lan:8502
享受服务(轮询)
浏览器访问http://localhost:8503/call
并反复刷新,返回如下两条信息交替显示,说明两个供应商的不服务交替被调用并返回执行结果。
Hello consul 1
或
Hello consul 2
参考
《纯洁的微笑》Blog
Cloud-Admin
springcloud(十三):注册中心 Consul 使用详解 <--重点
- 0
- 0
-
分享