【微服务】Spring Boot整合Consul

当前版本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是本机开的服务

enter description here

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

转载于:https://my.oschina.net/tree/blog/1594206

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值