一、搭建项目
父工程
pom
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <packaging>pom</packaging> <groupId>com.badcat</groupId> <artifactId>springCloud-demo</artifactId> <version>1.0-SNAPSHOT</version> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Greenwich.SR1</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.5.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.8</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.6.0</version> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> </plugins> </build> </project>
1、注册中心模块
pom
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>springCloud-demo</artifactId> <groupId>com.badcat</groupId> <version>1.0-SNAPSHOT</version> <relativePath>../../pom.xml</relativePath> </parent> <modelVersion>4.0.0</modelVersion> <packaging>jar</packaging> <artifactId>euraka-server</artifactId> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> </dependencies> </project>
application.properties
spring.application.name=eureka-server server.port=20000 eureka.instance.hostname=localhost ####是否向注册中心注册,因为是单节点注册中心,所以false eureka.client.register-with-eureka=false ####拉取注册中心表,不拉取 eureka.client.fetch-registry=false
启动类(注意@EnableEurekaServer)
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; /** * @author badcat * @date 2020-03-01 10:46 */ @SpringBootApplication @EnableEurekaServer public class EurekaServerApplication { public static void main(String[] args) { SpringApplication.run(EurekaServerApplication.class, args); } }
启动注册中心,访问http://localhost:20000/
2、搭建服务提供方模块
pom
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>springCloud-demo</artifactId> <groupId>com.badcat</groupId> <version>1.0-SNAPSHOT</version> <relativePath>../../pom.xml</relativePath> </parent> <modelVersion>4.0.0</modelVersion> <packaging>jar</packaging> <artifactId>eureka-client</artifactId> <name>eureka-client</name> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> </project>
application.properties
spring.application.name=eureka-client server.port=30000 eureka.client.serviceUrl.defaultZone=http://localhost:20000/eureka/
启动类(注意@EnableDiscoveryClient)
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; /** * @author badcat * @date 2020-03-01 11:25 */ @SpringBootApplication @EnableDiscoveryClient public class EurekaClientApplication { public static void main(String[] args) SpringApplication.run(EurekaClientApplication.class, args); } }
controller
import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; /** * @author badcat * @date 2020-03-01 11:27 */ @RestController @Slf4j public class Controller { @Value("${server.port}") private String port; @GetMapping("/sayHi") public String sayHi(){ return "this is " + port; } @PostMapping("/sayHi") public Friend sayHiPost( @RequestBody Friend friend){ log.error("you are " + friend.getName()); friend.setPort(port); return friend; } }
启动该模块,刷新刚才注册中心的页面,出现这个
调用接口试一下,两个接口都能调通
3、搭建服务消费者模块(目的是为了调用上一步骤的服务)
pom
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>springCloud-demo</artifactId> <groupId>com.badcat</groupId> <version>1.0-SNAPSHOT</version> <relativePath>../../pom.xml</relativePath> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>eureka-consumer</artifactId> <name>eureka-consume</name> <packaging>jar</packaging> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-actuator</artifactId> </dependency> </dependencies> </project>
application.properties
spring.application.name=eureka-consumer server.port=31000 eureka.client.serviceUrl.defaultZone=http://localhost:20000/eureka/
启动类(注意@EnableDiscoveryClient、RestTemplate )
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.context.annotation.Bean; import org.springframework.web.client.RestTemplate; /** * @author badcat * @date 2020-03-01 15:42 */ @SpringBootApplication @EnableDiscoveryClient public class EurekaConsumerApplication { @Bean public RestTemplate register(){ return new RestTemplate(); } public static void main(String[] args) { SpringApplication.run(EurekaConsumerApplication.class, args); } }
controller
import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.loadbalancer.LoadBalancerClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; /** * @author badcat * @date 2020-03-01 15:43 */ @RestController @Slf4j public class Controller { @Autowired private LoadBalancerClient client; @Autowired private RestTemplate restTemplate; @GetMapping("/hello") public String hello(){ //获取注册中心已注册的服务 ServiceInstance instance = client.choose("eureka-client"); if (instance == null){ return "no available instances"; } String format = String.format("http://%s:%s/sayHi", instance.getHost(), instance.getPort()); log.error("url is {}", format); return restTemplate.getForObject(format, String.class); } @PostMapping("/hello") public Friend helloPost(){ ServiceInstance instance = client.choose("eureka-client"); if (instance == null){ return null; } String format = String.format("http://%s:%s/sayHi", instance.getHost(), instance.getPort()); log.error("url is {}", format); Friend friend = new Friend(); friend.setName("eureka consumer"); return restTemplate.postForObject(format, friend, Friend.class); } }
启动该模块,刷新注册中心页面
调用接口试一下
4、服务续约与剔除
服务注册方(以eureka-client模块为例)
application.properties中添加如下配置
# 每隔5秒钟,向服务注册中心发送一条续约指令 eureka.instance.lease-renewal-interval-in-seconds=5 # 如果30秒依然没有收到续约请求,判定服务过期 eureka.instance.lease-expiration-duration-in-seconds=30
注册中心
application.properties中添加如下配置(关闭自保机制,每10秒提出一次过期的服务)
# 强制关闭自保(自动开关不起作用) eureka.server.enable-self-preservation=false # 每隔多久触发一次剔除(10秒) eureka.server.eviction-interval-timer-in-ms=10000
测试剔除功能,将eureka-client的判定过期时间由30秒改为5秒、发送续约间隔由5秒改为60秒,也就是说改服务一定会过期
重启一下注册中心和eureka-client,不停刷新注册中心的那个页面,你会发现一开始eureka-client是注册成功的,几秒之后消失了。查看注册中心的控制台,发现剔除日志:
5、注册中心高可用
重新搭建两个注册中心
只贴出application.properties(注意eureka.client.service-url.defaultZone)
spring.application.name=eureka-server-peer1 server.port=20001 eureka.instance.hostname=peer1 eureka.client.service-url.defaultZone=http://peer2:40001/eureka
spring.application.name=eureka-server-peer2 server.port=40001 eureka.instance.hostname=peer2 eureka.client.service-url.defaultZone=http://peer1:20001/eureka
启动这两个注册中心,访问http://localhost:40001/,出现这个,说明成功
我们将之前的eureka-client只注册到peer1上,看看peer2上能不能也拿到eureka-client的信息
eureka-client的application.properties(注意eureka.client.serviceUrl.defaultZone是配置的20001端口,也就是peer1)
spring.application.name=eureka-client server.port=30000 eureka.client.serviceUrl.defaultZone=http://peer1:20001/eureka/
启动eureka-client,刷新http://localhost:20001/和http://localhost:40001/,两个页面都会发现eureka-client信息,说明两个peer1和peer2是相互通信的
一般来说,我们应该将eureka-client同时配置两个注册中心,所以eureka-client的application.properties应该是这个样,但是这不是同时注册到两个注册中心,而是注册到第一个可用的注册中心,然后再由注册中心来传递eureka-client的信息
spring.application.name=eureka-client server.port=30000 eureka.client.serviceUrl.defaultZone=http://peer1:20001/eureka/,http://peer2:40001/eureka/
原文:https://www.cnblogs.com/hmxs/p/12683256.html