当前版本1.0.2
Consul介绍
Consul 是一个提供服务发现、健康检测、K/V 存储支持分布式高可用多数据中心的服务软件。
下载地址:https://www.consul.io/downloads.html
文档地址:https://www.consul.io/docs/index.html
教程:https://segmentfault.com/a/1190000005026002
项目整体部署策略
一共开启6台虚拟机ip分别为:
- 192.168.0.181 :consul-server集群1
- 192.168.0.182 :consul-server集群2
- 192.168.0.183 :consul-server集群3
- 192.168.0.184 :consul-service服务1
- 192.168.0.185 :consul-service服务2
- 192.168.0.186 :consul-service服务3
启动consul服务集群
192.168.0.181启动命令:
/opt/soft/consul/consul agent -server -bootstrap -data-dir /data/consul/data -node=agent-1 -bind=0.0.0.0 -config-dir /data/consul/conf -datacenter dc1 -ui
192.168.0.182启动命令,加入181服务集群
/opt/soft/consul/consul agent -server -data-dir /data/consul/data -node=agent-2 -bind=0.0.0.0 -config-dir /data/consul/conf -datacenter dc1 -ui -retry-join "192.168.0.181"
192.168.0.183启动命令,加入181服务集群
/opt/soft/consul/consul agent -server -data-dir /data/consul/data -node=agent-3 -bind=0.0.0.0 -config-dir /data/consul/conf -datacenter dc1 -ui -retry-join "192.168.0.181"
启动后使用./consul members命令查看状态,192.168.0.107是本机开的服务
spring-boot-consul-service项目
Pom里加入依赖引用
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring.cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
</dependencies>
application.yml配置文件
server:
port: 17003
application:
name: spring-boot-consul-service
spring:
http:
encoding:
charset: utf-8
enabled: true
cloud:
consul:
host: 127.0.0.1
port: 8500
discovery:
enabled: true
service-name: ${server.application.name}
health-check-interval: 10s
register: true
tags: foo=bar, baz
health-check-path: /health
WebConsulServiceApplication启动类
@SpringBootApplication
@EnableDiscoveryClient
public class WebConsulServiceApplication extends SpringBootServletInitializer {
private static final Logger logger = LoggerFactory.getLogger(WebConsulServiceApplication.class);
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return configureApplication(builder);
}
private static SpringApplicationBuilder configureApplication(SpringApplicationBuilder builder) {
return builder.sources(WebConsulServiceApplication.class).bannerMode(Banner.Mode.CONSOLE).registerShutdownHook(true).web(true);
}
public static void main(String[] args) {
logger.info("Application start....");
configureApplication(new SpringApplicationBuilder()).run(args);
logger.info("Application end....");
}
}
HelloController提供服务接口
@RestController
@RequestMapping(value="/service")
public class HelloController {
private static final Logger logger = LoggerFactory.getLogger(HelloController.class);
@Autowired
private DiscoveryClient client;
@Value("${server.port}")
private Integer port;
@Autowired
private LoadBalancerClient loadBalancer;
@RequestMapping(value = "/add", method = RequestMethod.GET)
public String add(@RequestParam Integer a, @RequestParam Integer b){
ServiceInstance instance = client.getLocalServiceInstance();
Integer r = a+b;
String s = "/add, host:"+instance.getHost() + ", service_id:" + instance.getServiceId() + "; result : "+r+"; port:" + port;
logger.info(s);
return s;
}
@RequestMapping(value = "/get/{serviceName}", method = RequestMethod.GET)
public List<ServiceInstance> get(@PathVariable String serviceName){
List<ServiceInstance> ls = client.getInstances(serviceName);
return ls;
}
@RequestMapping(value = "/geturl/{serviceName}", method = RequestMethod.GET)
public String getUrl(@PathVariable String serviceName){
return loadBalancer.choose("consul-server").getUri().toString();
}
}
服务打包放入192.168.0.184-186,服务启动以后访问健康检查地址:http://192.168.0.184:17003/health 访问后提示类似如下错误:
{
"status": "DOWN",
"diskSpace": {
"status": "UP",
"total": 241207078912,
"free": 63632199680,
"threshold": 10485760
},
"refreshScope": {
"status": "UP"
},
"consul": {
"status": "DOWN",
"services": {
"consul": [ ],
"spring-boot-consul-service": [ ]
},
"error": "java.lang.IllegalArgumentException: Value must not be null"
}
}
consul提示DOWN,这个问题一直困扰了好几天,直到在stackoverflow翻到这个: https://stackoverflow.com/questions/30736514/spring-boot-actuator-health-returning-down
因为我spring-cloud使用的是Dalston.SR4版本,这个版本spring-boot-consul-discovery是1.2.0,然而consul升级到1.x以后会有bug,需要把spring-boot-consul-discovery升级到1.3.0。然后使用Edgware.RELEASE版本重新启动,恢复正常
{
description: "Composite Discovery Client",
status: "UP"
}
由于部署的时候统一打包,启动后本机consul的健康监测使用的是hostname作为域名段,经过验证设置spring.cloud.consul.discovery.hostnames为本机ip即可,但是不想每台机器分别打包,考虑使用-Dspring.cloud.consul.discovery.hostname将本机ip带入,因此调整启动脚本
#!/bin/bash
local_ip="`/sbin/ifconfig -a|grep inet|grep -v 127.0.0.1|grep -v inet6|awk '{print $2}'|tr -d "addr:"`"
echo $local_ip
java -Dserver.port=17003 -Dspring.cloud.consul.discovery.hostname=$local_ip -jar /opt/app/spring-boot-consul-service/spr
ing-boot-consul-service-1.0-SNAPSHOT.jar
启动后恢复正常
访问http://192.168.0.184:17003/service/get/spring-boot-consul-service 查看服务状态:
[
{
"serviceId": "spring-boot-consul-service",
"host": "192.168.0.184",
"port": 17003,
"secure": false,
"metadata": {
"foo": "bar",
"baz": "baz"
},
"uri": "http://192.168.0.184:17003"
},
{
"serviceId": "spring-boot-consul-service",
"host": "192.168.0.185",
"port": 17003,
"secure": false,
"metadata": {
"foo": "bar",
"baz": "baz"
},
"uri": "http://192.168.0.185:17003"
},
{
"serviceId": "spring-boot-consul-service",
"host": "192.168.0.186",
"port": 17003,
"secure": false,
"metadata": {
"foo": "bar",
"baz": "baz"
},
"uri": "http://192.168.0.186:17003"
}
]
spring-boot-consul-client 请求service
pom文件
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
</dependencies>
ServiceFeignClient 访问spring-boot-consul-service接口
@FeignClient(name = "spring-boot-consul-service",
value = "spring-boot-consul-service")
public interface ServiceFeignClient {
@RequestMapping(method = RequestMethod.GET, value = "/service/hi")
public String hi();
@RequestMapping(method = RequestMethod.GET, value = "/service/add")
public String add(@RequestParam(name = "a") Integer a, @RequestParam(name = "b") Integer b);
@RequestMapping(method = RequestMethod.GET, value = "/get/{serviceName}")
public List<ServiceInstance> get(@PathVariable(name = "serviceName") String serviceName);
@RequestMapping(value = "/geturl/{serviceName}", method = RequestMethod.GET)
public String getUrl(@PathVariable(name = "serviceName") String serviceName);
}
ConsulClientHelloController提供对外接口服务
@Autowired
private ServiceFeignClient serviceFeignClient;
@RequestMapping(value = "/add", method = RequestMethod.GET)
public String add(@RequestParam Integer a, @RequestParam Integer b){
ServiceInstance instance = client.getLocalServiceInstance();
Integer r = a+b;
String s = "/add, host:"+instance.getHost() + ", service_id:" + instance.getServiceId() + "; result : "+r+"; port:" + port;
logger.info(s);
return s+"-------------"+serviceFeignClient.add(a, b);
}
启动后访问接口:
http://192.168.0.107:17004/service/add?a=1&b=2 刷新几次,分别返回如下数据;
/add, host:192.168.0.107, service_id:application-17004; result : 3; port:17004-------------/add, host:192.168.0.184, service_id:application-17003; result : 3; port:17003
/add, host:192.168.0.107, service_id:application-17004; result : 3; port:17004-------------/add, host:192.168.0.185, service_id:application-17003; result : 3; port:17003
/add, host:192.168.0.107, service_id:application-17004; result : 3; port:17004-------------/add, host:192.168.0.186, service_id:application-17003; result : 3; port:17003
可以看到每次访问的后端ip分别不同。
项目地址: https://github.com/treeyh/java-demo/tree/master/spring-boot-demo/spring-boot-consul
本文地址:https://my.oschina.net/tree/blog/1594206