1.1 安装Consul
1.1.1 安装三个Consul服务
192.168.56.12:8300作为Consul node1(leader)
192.168.56.12:8400作为Consul node2
192.168.56.12:8500作为Consul node3
1.1.2 使用Docker安装Consul
l 搜索镜像
docker search consul
l 下载镜像
docker pull progrium/consul
l 安装镜像
#consul 服务端 node1
docker run -d -h node1 --name consul_node1 --restart=always \
-v /data/consul:/consul/data \
-p 8300:8300 -p 8301:8301 -p 8301:8301/udp -p 8302:8302 -p 8302:8302/udp -p 8400:8400 -p 8500:8500 \
-e 'CONSUL_LOCAL_CONFIG={"skip_leave_on_interrupt": true}' \
-e CONSUL_BIND_INTERFACE=eth0 \
progrium/consul -server -bootstrap
#获取 node1 的IP
JOIN_IP="$(docker inspect -f '{{.NetworkSettings.IPAddress}}' consul_node1)"
#consul 服务端 node2
docker run --name consul_node2 -d --restart=always \
-e 'CONSUL_LOCAL_CONFIG={"skip_leave_on_interrupt": true}' \
-e CONSUL_BIND_INTERFACE=eth0 \
progrium/consul -h node2 –server -join $JOIN_IP
#consul 服务端 node3
docker run --name consul_node3 -d --restart=always \
-e 'CONSUL_LOCAL_CONFIG={"skip_leave_on_interrupt": true}' \
-e CONSUL_BIND_INTERFACE=eth0 \
progrium/consul –h node3 -server -join $JOIN_IP
agent : 表示启动 Agent 进程。
-server:表示启动 Consul Server 模式。
-client:表示启动 Consul Cilent 模式。
-bootstrap:表示这个节点是 Server-Leader ,每个数据中心只能运行一台服务器。技术角度上讲 Leader 是通过 Raft 算法选举的,但是集群第一次启动时需要一个引导 Leader,在引导群集后,建议不要使用此标志。
-ui:表示启动 Web UI 管理器,默认开放端口 8500,所以上面使用 Docker 命令把 8500 端口对外开放。
-node:节点的名称,集群中必须是唯一的。
-client:表示 Consul 将绑定客户端接口的地址,0.0.0.0 表示所有地址都可以访问。
-join:表示加入到某一个集群中去。 如:-json=192.168.1.23
l 看集群成员
docker exec -t consul_node1 consul members
docker exec -t consul_node1 consul operator raft list-peers
1.1.3 安装完成,使用WebUI查看结果
访问路径:http://192.168.56.10:8500/ui/#/dc1/services/consul
1.2 创建Consul的服务端
1.2.1 创建SpringCloud项目,选择相关组件如下:
pom.xml如下
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
1.2.2 配置Consul服务端
spring:
application:
name: service-provider
cloud:
consul:
discovery:
health-check-path: /actuator/health # 健康健康路径,也可以自己写
health-check-interval: 10s # 检测轮训时间 1m 代码1分钟
#instance-id: consul-client00 实例ID,唯一值
instance-id: ${spring.application.name}:${vcap.application.instance_id:${spring.application.instance_id:${random.value}}}
host: 192.168.56.10
port: 8500
1.2.3 设置启动类
@EnableDiscoveryClient
@SpringBootApplication
public class SpringBootConsulApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootConsulApplication.class, args);
}
}
1.2.4 创建相关服务的RestController
@RestController
public class HelloController {
@RequestMapping("/hello")
public @ResponseBody User hello() {
return new User(1, "hello consul");
}
}
1.2.5 启动项目,在Consul中查看已注册的服务
1.3 创建Consul的消费端
1.3.1 创建SpringCloud项目(项目结构同消费端)
1.3.2 配置Consul消费端
server.port=8504
spring.application.name=service-consumer
spring.cloud.consul.host=192.168.56.10
spring.cloud.consul.port=8500
#设置不需要注册到 consul 中
spring.cloud.consul.discovery.register=false
1.3.3 测试调用服务端Rest服务
@RestController
public class ServiceController {
@Autowired
private LoadBalancerClient loadBalancer;
@Autowired
private DiscoveryClient discoveryClient;
/**
* 获取所有服务
*/
@RequestMapping("/services")
public Object services() {
return discoveryClient.getInstances("service-provider");
}
/**
* 从所有服务中选择一个服务(轮询)
*/
@RequestMapping("/discover")
public Object discover() {
return loadBalancer.choose("service-provider ").getUri().toString();
}
}
Controller 中有俩个方法,一个是获取所有服务名为service-producer的服务信息并返回到页面,一个是随机从服务名为service-producer的服务中获取一个并返回到页面。
1.3.4 启动项目,访问Services服务:http://127.0.0.1:8504/services,返回结果如下:
[{"instanceId":"service-provider-cf29b1b84a0110cef01bca2bf6607c93","serviceId":"service-provider","host":"192.168.2.115","port":8503,"secure":false,"metadata":{"secure":"false"},"uri":"http://192.168.2.115:8503","scheme":null}]
1.3.5 使用RestTemplate访问服务端接口
/**
* 调用远程接口
*
* @return
*/
@RequestMapping("/call")
public User call() {
ServiceInstance serviceInstance = loadBalancer.choose("service-provider");
System.out.println("服务地址:" + serviceInstance.getUri());
System.out.println("服务名称:" + serviceInstance.getServiceId());
User callServiceResult = new RestTemplate().getForObject(serviceInstance.getUri().toString() + "/hello",
User.class);
System.out.println(callServiceResult);
return callServiceResult;
}
1.3.6 使用Feign访问服务端接口
1.3.6.1 设置启动类
@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class SpringBootConsulApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootConsulApplication.class, args);
}
}
1.3.6.2 Feign服务类
@FeignClient(name= "service-provider")
public interface HelloRemoteService {
@RequestMapping(value = "/hello")
public User hello(@RequestParam(value = "id") int id);
}
1.3.6.3 测试调用类
@Autowired
private HelloRemoteService userService;
/**
* 使用Feign,调用远程接口
*
* @return
*/
@RequestMapping("/FeignCall")
public User FeignCall(@RequestParam(value = "id") int id) {
User callServiceResult = userService.hello(id);
System.out.println(callServiceResult);
return callServiceResult;
}
1.4 Consul移除无效的服务
http://192.168.56.10:8500/v1/agent/service/deregister/<serviceID>
serviceID如下截图:
删除无效的节点
http://192.168.56.10:8500/v1/agent/force-leave/4b36b27317a0
1.5 GitHub代码地址
https://github.com/KentTain/SpringCloudDemo.git