- Eureka基础知识
- 什么是服务治理
- 什么是服务注册与发现
- 单机Eureka构建步骤
- 新建模块004-eureka-server7001
- 主启动
- 测试
- 将001-cloud-provider-payment-eureka-8001注册进Eureka
- 测试
- 将002-cloud-provider-order-eureka80注册进Eureka
- 测试
- 集群Eureka构建步骤
- 集群环境搭建步骤
- 修改映射配置
- 重新配置YML
- 主启动
- 将支付服务8001微服务发布到集群配置中
- 将订单服务80微服务发布到上面2台Eureka集群配置中
- 测试
- 支付服务提供者8002集群环境构建
- 测试
- 服务发现Discovery
- Eureka自我保护
涉及代码地址:https://gitee.com/codinginn/SpringCloudTurorial/tree/master/SpringCloudModules
思维导图和相关安装包:https://pan.baidu.com/s/1ogGF8sQrMxYc4HrTmjh9mA?pwd=aaaa 提取码:aaaa Eureka基础知识 什么是服务治理
Spring Cloud 封装了 Netflix 公司开发的 Eureka 模块来实现服务治理在传统的RPC远程调用框架中,每个服务与服务之间依赖关系比较复杂,所以需要使用服务治理,管理服务与服务之间的依赖关系,可以实现服务调用、负载均衡、容错等,实现服务发现与注册。
什么是服务注册与发现Eureka采用了CS的设计架构,Eureka Server 作为服务注册功能的服务器,它是服务注册中心,而系统中的其他微服务,使用 Eureka的客户端连接到 Eureka Server并维持心跳连接,这样系统的维护人员就可以通过 Eureka Server 来监控系统中各个微服务是否正常运行。
在服务注册与发现中,有一个注册中心。当服务器启动的时候,会把当前自己服务器的信息 比如 服务地址通讯地址等以别名方式注册到注册中心上。另一方(消费者|服务提供者),以该别名的方式去注册中心上获取到实际的服务通讯地址。在任何rpc远程框架中,都会有一个注册中心(存放服务地址相关信息(接口地址))
下图是Eureka系统架构:
- pom.xml
SpringCloudModules com.hashnode 1.0-SNAPSHOT 4.0.0 004-eureka-server7001 8 8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-actuator org.springframework.boot spring-boot-starter-test test org.junit.vintage junit-vintage-engine com.hashnode 003-cloud-api-commons 1.0-SNAPSHOT org.springframework.cloud spring-cloud-starter-netflix-eureka-server mysql mysql-connector-java com.alibaba druid junit junit log4j log4j org.springframework.boot spring-boot-starter-thymeleaf org.webjars bootstrap org.projectlombok lombok
- applicaiton.yml
server:
port: 7001
eureka:
instance:
#单点配置
hostname: localhost #eureka服务端的实例名称
client:
#false表示不向注册中心注册自己
register-with-eureka: false
#false表示自己就是注册中心,职责是维护服务实例,不需要检索服务
fetch-registry: false
service-url:
#设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
主启动
package com.hashnode;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class EurekaMain7001 {
public static void main(String[] args) {
SpringApplication.run(EurekaMain7001.class,args);
}
}
测试
将001-cloud-provider-payment-eureka-8001注册进Eureka
未注册进Eureka的模块001-cloud-provider-payment-eureka-8001参考:https://blog.csdn.net/qq_21898647/article/details/124225600
- 修改POM:
SpringCloudModules com.hashnode 1.0-SNAPSHOT 4.0.0 001-cloud-provider-payment-eureka-80018 8 org.springframework.boot spring-boot-starter-weborg.springframework.boot spring-boot-starter-actuatororg.springframework.boot spring-boot-starter-testtest org.junit.vintage junit-vintage-engineorg.springframework.cloud spring-cloud-starter-netflix-eureka-clientcom.hashnode 003-cloud-api-commons1.0-SNAPSHOT mysql mysql-connector-javacom.alibaba druidorg.mybatis.spring.boot mybatis-spring-boot-starterjunit junitlog4j log4jorg.springframework.boot spring-boot-starter-thymeleaforg.webjars bootstraporg.projectlombok lombok
- 改YML
server:
port: 8001
spring:
application:
name: cloud-payment-service
datasource:
type: com.alibaba.druid.pool.DruidDataSource #当前数据源操作类型
driver-class-name: org.gjt.mm.mysql.Driver #mysql驱动包
url: jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDateTimeCode=false&serverTimezone=GMT%2B8
username: root
password: root
eureka:
client:
#表示是否将自己注册进EurekaServer默认为true
register-with-eureka: true
#是否从EurekaServer抓取已有的注册信息,默认为true,单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
fetch-registry: true
service-url:
defaultZone: http://localhost:7001/eureka
instance:
instance-id: payment8001
prefer-ip-address: true #访问路径可以显示IP地址
mybatis:
mapper-locations:
- classpath:mapper/*.xml
type-aliases-package: com.hashnode.model #所有model所在包
- 主启动类
package com.hashnode;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
@MapperScan("com.hashnode.mapper")
@EnableEurekaClient
public class PaymentMainEureka8001 {
public static void main(String[] args) {
ConfigurableApplicationContext run = SpringApplication.run(PaymentMainEureka8001.class, args);
}
}
测试
先要启动004-eureka-server7001,然后启动001-cloud-provider-payment-eureka-8001,访问http://localhost:7001/:
微服务的名字对应于:
将002-cloud-provider-order-eureka80注册进Eureka未注册进Eureka的模块002-cloud-provider-order-eureka80参考:https://blog.csdn.net/qq_21898647/article/details/124225600
修改pom
SpringCloudModules com.hashnode 1.0-SNAPSHOT 4.0.0 002-cloud-provider-order-eureka80 8 8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-actuator org.springframework.boot spring-boot-starter-test test org.junit.vintage junit-vintage-engine org.springframework.cloud spring-cloud-starter-netflix-eureka-client com.hashnode 003-cloud-api-commons 1.0-SNAPSHOT mysql mysql-connector-java com.alibaba druid junit junit log4j log4j org.springframework.boot spring-boot-starter-thymeleaf org.webjars bootstrap org.projectlombok lombok
修改yml
server:
port: 80
spring:
application:
name: cloud-order-service
eureka:
client:
#表示是否将自己注册进EurekaServer默认为true
register-with-eureka: true
#是否从EurekaServer抓取已有的注册信息,默认为true,单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
fetch-registry: true
service-url:
defaultZone: http://localhost:7001/eureka
修改主启动类
package com.hashnode;
import com.hashnode.myrule.MySelfRule;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
@EnableEurekaClient
public class OrderMainEureka80 {
public static void main(String[] args) {
ConfigurableApplicationContext run = SpringApplication.run(OrderMainEureka80.class, args);
}
}
修改ApplicaitonContextConfig.java,使RestTemplate可以通过服务名调用远程服务,并且具有负载均衡的能力:
package com.hashnode.config;
import com.hashnode.model.Payment;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class ApplicationContextConfig {
@Bean
@LoadBalanced //负载均衡使用,从eureka寻找服务所在的域名 如果使用自定义的负载均衡,则不能使用此注解
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
@Bean
public Payment getPayment(){
return new Payment(0L,"000");
}
}
修改OrderController.java,不适用绝对ip,而使用服务名:
package com.hashnode.controller;
import com.hashnode.lb.LoadBalancer;
import com.hashnode.model.CommonResult;
import com.hashnode.model.Payment;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
import java.net.URI;
import java.util.List;
@RestController
@Slf4j
public class OrderController {
public static final String PAYMENT_URL = "http://CLOUD-PAYMENT-SERVICE";
@Autowired
private RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;
@Resource
private LoadBalancer loadBalancer;
@GetMapping("/consumer/payment/create")
public CommonResult create(Payment payment){
return restTemplate.postForObject(PAYMENT_URL+"/payment/create",payment,CommonResult.class);
}
@GetMapping("/consumer/payment/get/{id}")
public CommonResult getPayment(@PathVariable("id")Long id){
return restTemplate.getForObject(PAYMENT_URL+"/payment/get/"+id,CommonResult.class);
}
}
测试
服务调用:
集群Eureka构建步骤问题:微服务RPC远程服务调用最核心的是什么
答:高可用,试想你的注册中心只有一个, 如果注册中心出现,会导致整个为服务环境不可用。解决办法:搭建Eureka注册中心集群 ,实现负载均衡+故障容错
详细代码参考:https://gitee.com/codinginn/SpringCloudTurorial/tree/master/SpringCloudModules
集群环境搭建步骤参考004-eureka-server7001新建004-eureka-server7002,004-eureka-server7003。·
pom.xml
修改映射配置SpringCloudModules com.hashnode 1.0-SNAPSHOT 4.0.0 004-eureka-server7002 8 8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-actuator org.springframework.boot spring-boot-starter-test test org.junit.vintage junit-vintage-engine com.hashnode 003-cloud-api-commons 1.0-SNAPSHOT org.springframework.cloud spring-cloud-starter-netflix-eureka-server mysql mysql-connector-java com.alibaba druid junit junit log4j log4j org.springframework.boot spring-boot-starter-thymeleaf org.webjars bootstrap org.projectlombok lombok
找到找到C:WindowsSystem32driversetc路径下的hosts文件,并修改映射配置添进hosts文件:
# springcloud测试用 begin 127.0.0.1 eureka7001.com 127.0.0.1 eureka7002.com 127.0.0.1 eureka7003.com # springcloud测试用 end重新配置YML
- 7001
server:
port: 7001
eureka:
instance:
#单点配置
# hostname: localhost #eureka服务端的实例名称
# 模拟集群配置
hostname: eureka7001.com
client:
#false表示不向注册中心注册自己
register-with-eureka: false
#false表示自己就是注册中心,职责是维护服务实例,不需要检索服务
fetch-registry: false
service-url:
#设置于Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址
# defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
#模拟集群配置
defaultZone: http://eureka7002.com:7002/eureka,http://eureka7003.com:7003/eureka
- 7002
server:
port: 7002
eureka:
instance:
#单点配置
# hostname: localhost #eureka服务端的实例名称
# 模拟集群配置
hostname: eureka7002.com
client:
#false表示不向注册中心注册自己
register-with-eureka: false
#false表示自己就是注册中心,职责是维护服务实例,不需要检索服务
fetch-registry: false
service-url:
#设置于Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址
# defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
#模拟集群配置
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7003.com:7003/eureka
- 7003
server:
port: 7003
eureka:
instance:
#单点配置
# hostname: localhost #eureka服务端的实例名称
# 模拟集群配置
hostname: eureka7003.com
client:
#false表示不向注册中心注册自己
register-with-eureka: false
#false表示自己就是注册中心,职责是维护服务实例,不需要检索服务
fetch-registry: false
service-url:
#设置于Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址
# defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
#模拟集群配置
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
主启动
package com.hashnode;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class EurekaMain7002 {
public static void main(String[] args) {
SpringApplication.run(EurekaMain7002.class,args);
}
}
将支付服务8001微服务发布到集群配置中
修改YML
server:
port: 8001
spring:
application:
name: cloud-payment-service
datasource:
type: com.alibaba.druid.pool.DruidDataSource #当前数据源操作类型
driver-class-name: org.gjt.mm.mysql.Driver #mysql驱动包
url: jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDateTimeCode=false&serverTimezone=GMT%2B8
username: root
password: root
eureka:
client:
#表示是否将自己注册进EurekaServer默认为true
register-with-eureka: true
#是否从EurekaServer抓取已有的注册信息,默认为true,单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
fetch-registry: true
service-url:
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka,http://eureka7003.com:7003/eureka
# defaultZone: http://localhost:7001/eureka
instance:
instance-id: payment8001
prefer-ip-address: true #访问路径可以显示IP地址
mybatis:
mapper-locations:
- classpath:mapper/*.xml
type-aliases-package: com.hashnode.model #所有model所在包
将订单服务80微服务发布到上面2台Eureka集群配置中
server:
port: 80
spring:
application:
name: cloud-order-service
eureka:
client:
#表示是否将自己注册进EurekaServer默认为true
register-with-eureka: true
#是否从EurekaServer抓取已有的注册信息,默认为true,单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
fetch-registry: true
service-url:
defaultZone: http://localhost:7001/eureka,http://localhost:7002/eureka,http://localhost:7003/eureka
# defaultZone: http://localhost:7001/eureka
设置002-cloud-provider-order-eureka80使RestTemplate具有负载均衡的能力。
- ApplicationContextConfig.java
package com.hashnode.config;
import com.hashnode.model.Payment;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class ApplicationContextConfig {
@Bean
@LoadBalanced //负载均衡使用,从eureka寻找服务所在的域名 如果使用自定义的负载均衡(@RibbonClient(name = "CLOUD-ORDER-SERVICE",configuration = MySelfRule.class)),则不能使用此注解
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
@Bean
public Payment getPayment(){
return new Payment(0L,"000");
}
}
测试
启动EurekaServer,7001/7002/7003,再启动服务提供者provider8001,消费者80:
访问http://localhost/consumer/payment/get/1,因为80是默认端口,所以不用加端口号
支付服务提供者8002集群环境构建参考001-cloud-provider-payment-eureka-8001新建005-cloud-provider-payment-eureka-8002
pom.xml
SpringCloudModules com.hashnode 1.0-SNAPSHOT 4.0.0 005-cloud-provider-payment-eureka-8002 8 8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-actuator org.springframework.boot spring-boot-starter-test test org.junit.vintage junit-vintage-engine org.springframework.cloud spring-cloud-starter-netflix-eureka-client com.hashnode 003-cloud-api-commons 1.0-SNAPSHOT mysql mysql-connector-java com.alibaba druid org.mybatis.spring.boot mybatis-spring-boot-starter junit junit log4j log4j org.springframework.boot spring-boot-starter-thymeleaf org.webjars bootstrap org.projectlombok lombok
配置yml
server:
port: 8002
spring:
application:
name: cloud-payment-service
datasource:
type: com.alibaba.druid.pool.DruidDataSource #当前数据源操作类型
driver-class-name: org.gjt.mm.mysql.Driver #mysql驱动包
url: jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDateTimeCode=false&serverTimezone=GMT%2B8
username: root
password: root
eureka:
client:
#表示是否将自己注册进EurekaServer默认为true
register-with-eureka: true
#是否从EurekaServer抓取已有的注册信息,默认为true,单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
fetch-registry: true
service-url:
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka,http://eureka7003.com:7003/eureka
instance:
instance-id: payment8002
prefer-ip-address: true #访问路径可以显示IP地址
mybatis:
mapper-locations:
- classpath:mapper/*.xml
type-aliases-package: com.hashnode.model #所有model所在包
主启动类
package com.hashnode;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
@MapperScan("com.hashnode.mapper")
@EnableEurekaClient
public class PaymentMainEureka8002 {
public static void main(String[] args) {
ConfigurableApplicationContext run = SpringApplication.run(PaymentMainEureka8002.class, args);
}
}
业务类和8001一样。
修改8001/8002的Controller
- 8001
package com.hashnode.controller;
import com.hashnode.model.CommonResult;
import com.hashnode.model.Payment;
import com.hashnode.service.PaymentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;
@RestController
@Slf4j
public class PaymentController {
@Resource
private PaymentService paymentService;
@Value("${server.port}")
private String serverPort;
@PostMapping(value = "/payment/create")
public CommonResult create(@RequestBody Payment payment){
int result = paymentService.createPaymentSelective(payment);
log.info("插入结果"+result);
if(result > 0){
return new CommonResult(200,"插入数据库成功",payment);
}else{
return new CommonResult(444,"插入数据库失败",null);
}
}
@GetMapping(value = "/payment/get/{id}")
public CommonResult getPaymentById(@PathVariable("id") Long id){
System.out.println(111);
Payment result = paymentService.getPaymentById(id);
log.info("查询结果"+result);
if(result != null){
return new CommonResult(200,"查询成功 port:"+serverPort,result);
}else {
return new CommonResult(444,"没有对应记录,查询ID:"+id);
}
}
@GetMapping(value = "/payment/feign/timeout")
public String paymentFeignTimeout(){
try {
TimeUnit.SECONDS.sleep(3);
}catch (Exception e){
e.printStackTrace();
}
return serverPort;
}
}
- 8002
package com.hashnode.controller;
import com.hashnode.model.CommonResult;
import com.hashnode.model.Payment;
import com.hashnode.service.PaymentService;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.C;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.TimeUnit;
@RestController
@Slf4j
@EnableDiscoveryClient
public class PaymentController {
@Resource
private PaymentService paymentService;
@Value("${server.port}")
private String serverPort;
@Resource
private DiscoveryClient discoveryClient;
@PostMapping(value = "/payment/create")
public CommonResult create(@RequestBody Payment payment){
int result = paymentService.createPaymentSelective(payment);
log.info("插入结果"+result);
if(result > 0){
return new CommonResult(200,"插入数据库成功 port:"+serverPort,payment);
}else{
return new CommonResult(444,"插入数据库失败",null);
}
}
@GetMapping(value = "/payment/get/{id}")
public CommonResult getPaymentById(@PathVariable("id") Long id){
System.out.println(111);
Payment result = paymentService.getPaymentById(id);
log.info("查询结果"+result);
if(result != null){
return new CommonResult(200,"查询成功+ip:"+serverPort,result);
}else {
return new CommonResult(444,"没有对应记录,查询ID:"+id);
}
}
@GetMapping(value = "/payment/discovery")
public Object discovery(){
List services = discoveryClient.getServices();
for (String service : services) {
log.info("******element"+service);
}
List instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");
for (ServiceInstance instance : instances){
log.info(instance.getServiceId()+"t" + instance.getHost()+"t"+instance.getPort() + "t" + instance.getUri());
}
return this.discoveryClient;
}
@GetMapping(value = "/payment/feign/timeout")
public String paymentFeignTimeout(){
try {
TimeUnit.SECONDS.sleep(3);
}catch (Exception e){
e.printStackTrace();
}
return serverPort;
}
}
测试
先要启动EurekaServer,7001/7002/7003服务,然后启动服务提供者provider,8001/8002服务,然后启动80
多次访问http://localhost/consumer/payment/get/31, 端口号为8001和8002的服务交替调用,结果如下:
服务发现Discovery修改001-cloud-provider-payment-eureka-8001的Controller
package com.hashnode.controller;
import com.hashnode.model.CommonResult;
import com.hashnode.model.Payment;
import com.hashnode.service.PaymentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.TimeUnit;
@RestController
@Slf4j
public class PaymentController {
@Resource
private PaymentService paymentService;
@Value("${server.port}")
private String serverPort;
@Resource
private DiscoveryClient discoveryClient;
@PostMapping(value = "/payment/create")
public CommonResult create(@RequestBody Payment payment){
int result = paymentService.createPaymentSelective(payment);
log.info("插入结果"+result);
if(result > 0){
return new CommonResult(200,"插入数据库成功",payment);
}else{
return new CommonResult(444,"插入数据库失败",null);
}
}
@GetMapping(value = "/payment/get/{id}")
public CommonResult getPaymentById(@PathVariable("id") Long id){
System.out.println(111);
Payment result = paymentService.getPaymentById(id);
log.info("查询结果"+result);
if(result != null){
return new CommonResult(200,"查询成功 port:"+serverPort,result);
}else {
return new CommonResult(444,"没有对应记录,查询ID:"+id);
}
}
@GetMapping(value = "/payment/discovery")
public Object discovery(){
List services = discoveryClient.getServices();
for (String service : services) {
log.info("******element"+service);
}
List instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");
for (ServiceInstance instance : instances){
log.info(instance.getServiceId()+"t" + instance.getHost()+"t"+instance.getPort() + "t" + instance.getUri());
}
return this.discoveryClient;
}
}
主启动类添加@EnableDiscoveryClient 用于服务发现
package com.hashnode;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
@MapperScan("com.hashnode.mapper")
@EnableEurekaClient
@EnableDiscoveryClient //服务发现
public class PaymentMainEureka8001 {
public static void main(String[] args) {
ConfigurableApplicationContext run = SpringApplication.run(PaymentMainEureka8001.class, args);
}
}
先启动EurekaServer,然后启8001/8002,访问http://localhost:8001/payment/discovery,结果如下:
Eureka自我保护若某时刻某一个微服务不可用了,Eureka不会立刻清理,依旧会对该微服务的信息进行保存,如果要及时对不可以的微服务进行清理,可以在服务端做如下配置:
server:
port: 7001
eureka:
instance:
#单点配置
# hostname: localhost #eureka服务端的实例名称
# 模拟集群配置
hostname: eureka7001.com
client:
#false表示不向注册中心注册自己
register-with-eureka: false
#false表示自己就是注册中心,职责是维护服务实例,不需要检索服务
fetch-registry: false
service-url:
#设置于Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址
# defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
#模拟集群配置
defaultZone: http://eureka7002.com:7002/eureka,http://eureka7003.com:7003/eureka
server:
enable-self-preservation: false #关闭自我保护机制,保证不可用服务被及时踢除
eviction-interval-timer-in-ms: 2000 #表示服务器在收到最后一次心跳之后等待的持续时间
也可以对客户端8001的yml做如下配置:
server:
port: 8001
spring:
application:
name: cloud-payment-service
datasource:
type: com.alibaba.druid.pool.DruidDataSource #当前数据源操作类型
driver-class-name: org.gjt.mm.mysql.Driver #mysql驱动包
url: jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDateTimeCode=false&serverTimezone=GMT%2B8
username: root
password: root
eureka:
client:
#表示是否将自己注册进EurekaServer默认为true
register-with-eureka: true
#是否从EurekaServer抓取已有的注册信息,默认为true,单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
fetch-registry: true
service-url:
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka,http://eureka7003.com:7003/eureka
# defaultZone: http://localhost:7001/eureka
instance:
instance-id: payment8001
# prefer-ip-address: true #访问路径可以显示IP地址
#Eureka客户端向服务端发送心跳的时间间隔,单位为秒(默认是30秒)
lease-renewal-interval-in-seconds: 1
#Eureka服务端在收到最后一次心跳后等待时间上限,单位为秒(默认是90秒),超时将剔除服务
lease-expiration-duration-in-seconds: 2
mybatis:
mapper-locations:
- classpath:mapper/*.xml
type-aliases-package: com.hashnode.model #所有model所在包



