zoukankan      html  css  js  c++  java
  • spring cloud:搭建基于consul的服务提供者集群(spring cloud hoxton sr8 / spring boot 2.3.4)

    一,搭建基于consul的服务提供者集群

    1,consul集群,共3个实例:

    2, 服务提供者集群:共2个实例:

    3,服务消费者:一个实例即可

    4,consul集群的搭建,请参考:

    https://www.cnblogs.com/architectforest/p/13735545.html

    5,演示例子实现生产环境中需要的高可用:

                 consul server集群和服务提供者集群

    说明:刘宏缔的架构森林是一个专注架构的博客,地址:https://www.cnblogs.com/architectforest

             对应的源码可以访问这里获取: https://github.com/liuhongdi/

    说明:作者:刘宏缔 邮箱: 371125307@qq.com

    二,演示项目的相关信息:

    1,两个项目的地址:

      服务提供者:

    https://github.com/liuhongdi/cloudconsul

      服务消费者:

    https://github.com/liuhongdi/consulconsumer

    2,项目的功能说明

               演示了基于consul实现的服务提供者和消费者,

                                基于consul集群和消费者集群

    3,服务提供者项目的结构:如图

    4,服务消费者项目的结构:如图

     

    三,服务提供者项目的配置文件说明

     1,pom.xml

            <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>

     2,application.properties

    spring.application.name=provider1
    server.port=8080
    #
    spring.cloud.consul.host=127.0.0.1
    spring.cloud.consul.port=8500
    spring.cloud.consul.discovery.service-name=lhdprovider
    spring.cloud.consul.discovery.prefer-ip-address=true
    spring.cloud.consul.discovery.instance-id=${spring.application.name}:${spring.cloud.client.ip-address}
    provider.name = p1

    3,application-provider2.properties

    spring.application.name=provider2
    server.port=8080
    #
    spring.cloud.consul.host=127.0.0.1
    spring.cloud.consul.port=8500
    spring.cloud.consul.discovery.service-name=lhdprovider
    spring.cloud.consul.discovery.prefer-ip-address=true
    spring.cloud.consul.discovery.instance-id=${spring.application.name}:${spring.cloud.client.ip-address}
    provider.name = p2

    说明:spring.cloud.consul.discovery.prefer-ip-address=true:

    这个配置项的作用是consul中提供的服务名称是ip和port,

    这样消费者可以直接访问服务提供者,否则的话,

    需要在运行服务消费者的机器上配置实例名称和ip的对应到 /etc/hosts当中才行

    四,服务提供者项目的java代码说明

    1,DemoApplication.java

    @EnableDiscoveryClient
    @SpringBootApplication
    public class DemoApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(DemoApplication.class, args);
        }
    
    }

    2,HomeController.java

    @RestController
    @RequestMapping("/home")
    public class HomeController {
    
        @Resource
        private DiscoveryClient discoveryClient;
    
        @Value("${provider.name}")
        private String name;
    
        @Value("${server.port}")
        private String port;
    
        // list services
        @GetMapping("/serviceslist")
        public Object serviceslist() {
            return discoveryClient.getServices();
        }
    
        // list instances in a service id
        @GetMapping("/instanceslist")
        public Object instanceslist() {
            return discoveryClient.getInstances("consul");
        }
    
        //test api
        @GetMapping("/hello")
        public String hello() {
            String ip = "";
            try {
            Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
            while (interfaces.hasMoreElements()) {
                NetworkInterface current = interfaces.nextElement();
                if (!current.isUp() || current.isLoopback() || current.isVirtual()) continue;
                Enumeration<InetAddress> addresses = current.getInetAddresses();
                while (addresses.hasMoreElements()) {
                    InetAddress addr = addresses.nextElement();
                    if (addr.isLoopbackAddress()) continue;
                    ip = addr.getHostAddress();
                }
            }
            } catch (SocketException e) {
                e.printStackTrace();
            }
            System.out.println("ip:"+ip);
            //return discoveryClient.getInstances("consul");
            String res = "ip:"+ip+";name:"+name+";port:"+port;
            return res;
        }
    }

    五,服务消费者项目的配置文件说明

    1,pom.xml

            <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>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-openfeign</artifactId>
            </dependency>

    2,application.properties

    spring.application.name=lhdconsumer
    spring.cloud.consul.host=localhost
    spring.cloud.consul.port=8500
    spring.cloud.consul.discovery.register=false
    server.port=8081

    六,服务消费者项目的java代码说明

    1,DemoApplication.java

    @SpringBootApplication
    @EnableDiscoveryClient
    @EnableFeignClients
    public class DemoApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(DemoApplication.class, args);
        }
    
    }

    2,HiService.java

    @Service
    public class HiService {
    
        @Resource
        HomeFeignClient homeFeignClient;
    
        public String sayHi(String name){
            return  homeFeignClient.sayHifromClient();
        }
    }

    3,HomeFeignClient.java

    @FeignClient(value="lhdprovider")
    public interface HomeFeignClient {
         @GetMapping(value="/home/hello")
         String sayHifromClient();
    }

    4,HomeController.java

    @RestController
    @RequestMapping("/home")
    public class HomeController {
    
        @Resource
        HiService hiService;
    
        @GetMapping("/hi")
        public String sayHi(){
            return hiService.sayHi();
        }
    }

    七,搭建服务提供者集群

    provider1上:

    1,启动consul

    [root@provider1 /]# nohup /usr/local/soft/consul agent -data-dir=/data/consul/data -node=provider1 -bind=172.17.0.5 -datacenter=dc1 -client=0.0.0.0 -join=172.17.0.2 > /dev/null 2>&1 & 

    2,启动服务:

    [root@provider1 /]# /usr/local/soft/jdk-13/bin/java -jar /usr/local/soft/demo-0.0.1-SNAPSHOT.jar

    provider2上:

    1,启动consul

    [root@provider2 /]# nohup /usr/local/soft/consul agent -data-dir=/data/consul/data -node=provider2 -bind=172.17.0.6 -datacenter=dc1 -client=0.0.0.0 -join=172.17.0.2 > /dev/null 2>&1 &  
    [1] 206

    2,启动服务:

    [root@provider2 /]# /usr/local/soft/jdk-13/bin/java -jar /usr/local/soft/demo-0.0.1-SNAPSHOT.jar --spring.profiles.active=provider2

    八,测试效果

    1,服务启动后,查看服务提供的情况:

    访问:

    http://172.17.0.5:8080/home/hello

    返回:

    ip:172.17.0.5;name:p1;port:8080

    访问:

    http://172.17.0.6:8080/home/hello

    返回:

    ip:172.17.0.6;name:p2;port:8080

    2,测试服务消费者:访问:

    http://127.0.0.1:8081/home/hi

    返回:

    ip:172.17.0.5;name:p1;port:8080

    刷新后返回:

    ip:172.17.0.6;name:p2;port:8080

    3,测试高可用:关掉服务:

    在provider2上,把服务停掉:

    直接ctrl-c关掉或者kill也可

    ip:172.17.0.6
    ip:172.17.0.6
    ^C2020-10-06 08:41:30.727  INFO 379 --- [extShutdownHook] o.s.s.c.ThreadPoolTaskScheduler          : Shutting down ExecutorService 'catalogWatchTaskScheduler'
    2020-10-06 08:41:30.738  INFO 379 --- [extShutdownHook] o.s.c.c.s.ConsulServiceRegistry          : Deregistering service with consul: provider2-172-17-0-6
    2020-10-06 08:41:30.780  INFO 379 --- [extShutdownHook] o.s.s.concurrent.ThreadPoolTaskExecutor  : Shutting down ExecutorService 'applicationTaskExecutor'

    然后查看consul的web ui:

     可以看到lhdprovider中只剩下了一个实例:

    访问服务消费者:

    http://127.0.0.1:8081/home/hi

    返回:

    ip:172.17.0.5;name:p1;port:8080

    反复刷新后返回结果中也没有provider2的返回,只有p1的返回,
    说明高可用有效

    4,测试高可用:关掉consul的agent

    把上面所掉的provider2的服务再次启动

    这次我们关掉provider1上的consul client

    [root@provider1 /]# ps auxfww
    USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
    root        495  0.5  0.0  12028  3012 pts/2    Ss   08:48   0:00 /bin/bash
    root        508  0.0  0.0  43964  3084 pts/2    R+   08:48   0:00  \_ ps auxfww
    root        200  0.0  0.0  12128   180 pts/1    Ss   01:16   0:00 /bin/bash
    root        239  0.4  0.5 784952 23788 pts/1    Sl   07:09   0:24  \_ /usr/local/soft/consul agent -data-dir=/data/consul/data -node=provider1 -bind=172.17.0.5 -datacenter=dc1 -client=0.0.0.0 -join=172.17.0.2
    root        453  0.8  2.2 3619488 91824 pts/1   Sl+  07:42   0:34  \_ /usr/local/soft/jdk-13/bin/java -jar /usr/local/soft/demo-0.0.1-SNAPSHOT.jar
    root          1  0.0  0.0  93860   376 ?        Ss   01:15   0:00 /usr/sbin/init
    root         25  0.0  0.0  91304  1176 ?        Ss   01:15   0:00 /usr/lib/systemd/systemd-journald
    root         33  0.0  0.0  88832    76 ?        Ss   01:15   0:00 /usr/lib/systemd/systemd-udevd
    dbus         66  0.0  0.0  52812     0 ?        Ss   01:15   0:00 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only
    [root@provider1 /]# kill 239
    [root@provider1 /]# kill 239
    [root@provider1 /]# kill 239
    bash: kill: (239) - No such process

    查看consul的web ui,只剩下了provider2

    访问消费者:

    http://127.0.0.1:8081/home/hi

    只返回:

    ip:172.17.0.6;name:p2;port:8080

    5,测试高可用:关掉consul集群中的一个:

    [root@consul1 /]# /usr/local/soft/consul leave
    Graceful leave complete
    [1]+  Done                    nohup /usr/local/soft/consul agent -server -bind=172.17.0.2 -client=0.0.0.0 -bootstrap-expect=2 -data-dir=/data/consul/da -node=server-2 > /dev/null 2>&1

    查看consul web ui,只剩下了两个实例

    进入查看:

     测试服务消费者:访问:

    http://127.0.0.1:8081/home/hi

    可以正常访问

    九,查看spring boot版本:

      .   ____          _            __ _ _
     /\ / ___'_ __ _ _(_)_ __  __ _    
    ( ( )\___ | '_ | '_| | '_ / _` |    
     \/  ___)| |_)| | | | | || (_| |  ) ) ) )
      '  |____| .__|_| |_|_| |_\__, | / / / /
     =========|_|==============|___/=/_/_/_/
     :: Spring Boot ::        (v2.3.4.RELEASE)
  • 相关阅读:
    使用golang访问kubebernetes
    使用 Rancher 管理现有 Kubernetes 集群
    Running powershell scripts during nuget package installation and removal
    How to Create, Use, and Debug .NET application Crash Dumps in 2019
    寻找写代码感觉(一)之使用 Spring Boot 快速搭建项目
    Selenium+Java之解决org.openqa.selenium.InvalidArgumentException: invalid argument报错问题
    Selenium环境搭建
    关于Xpath定位方法知道这些基本够用
    Web自动化之浏览器启动
    【翻译】编写代码注释的最佳实践
  • 原文地址:https://www.cnblogs.com/architectforest/p/13773638.html
Copyright © 2011-2022 走看看