一,搭建基於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)