问题:微服务RPC远程服务调用最核心的是什么
高可用,试想你的注册中心只有一个only one, 它出故障了那就呵呵( ̄▽ ̄)"了,会导致整个为服务环境不可用,所以
解决办法:搭建Eureka注册中心集群 ,实现负载均衡+故障容错
集群代码:
修改host文件
搭建俩个Eureka服务中心,端口号分别为7001 7002
7001yml文件:
server: port: 7001 eureka: instance: hostname: eureka7001.com #eureka服务端的实例名称 client: register-with-eureka: false #false表示不向注册中心注册自己。 fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务 service-url: defaultZone: http://eureka7002.com:7002/eureka/
7002yml文件:
server: port: 7002 eureka: instance: hostname: eureka7002.com #eureka服务端的实例名称 client: register-with-eureka: false #false表示不向注册中心注册自己。 fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务 service-url: defaultZone: http://eureka7001.com:7001/eureka/
7001启动类:
@SpringBootApplication @EnableEurekaServer public class EurekaMain7001 { public static void main(String[] args) { SpringApplication.run(EurekaMain7001.class,args); } }
7002启动类 :
@SpringBootApplication @EnableEurekaServer public class EurekaMain7002 { public static void main(String[] args) { SpringApplication.run(EurekaMain7002.class,args); } }
负载均衡实现代码:
假设现在80端口对外暴露,通过Eureka调用8001 8002的端口服务(负载均衡,俩者业务相同)
8001的yml文件
server: port: 8001 spring: application: name: cloud-payment-service datasource: type: com.alibaba.druid.pool.DruidDataSource # 当前数据源操作类型 driver-class-name: com.mysql.cj.jdbc.Driver # mysql驱动包 url: jdbc:mysql://localhost:3306/2019db?useSSL=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC username: root password: newroot mybatis: mapperLocations: classpath:mapper/*.xml type-aliases-package: com.lun.springcloud.entities # 所有Entity别名类所在包 eureka: client: #表示是否将自己注册进EurekaServer默认为true。 register-with-eureka: true #是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡 fetchRegistry: true service-url: defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka # 集群版 # defaultZone: http://localhost:7001/eureka
8002的yml文件
server: port: 8002 spring: application: name: cloud-payment-service datasource: type: com.alibaba.druid.pool.DruidDataSource # 当前数据源操作类型 driver-class-name: com.mysql.cj.jdbc.Driver # mysql驱动包 url: jdbc:mysql://localhost:3306/2019db?useSSL=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC username: root password: newroot mybatis: mapperLocations: classpath:mapper/*.xml type-aliases-package: com.lun.springcloud.entities # 所有Entity别名类所在包 eureka: client: #表示是否将自己注册进EurekaServer默认为true。 register-with-eureka: true #是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡 fetchRegistry: true service-url: defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka # 集群版 # defaultZone: http://localhost:7001/eureka
8001启动类
@SpringBootApplication @EnableEurekaClient public class PaymentMain8001 { public static void main(String[] args) { SpringApplication.run(PaymentMain8001.class,args); } }
8002启动类
@SpringBootApplication @EnableEurekaClient public class PaymentMain8002 { public static void main(String[] args) { SpringApplication.run(PaymentMain8002.class,args); } }
8001 8002 的业务处理部分(片段)(就是对数据库的增删改查部分mybatis)
@RestController @Slf4j @ResponseBody public class PaymentController { @Value("${server.port}") private String serverPort; @Resource private PaymentService paymentService; @PostMapping("/payment/create") public CommonResult create(@RequestBody Payment payment) { int result = paymentService.create(payment); log.info("***********插入成功"+result+"服务端口"+serverPort); if(result>0){ return new CommonResult(200,"插入数据成功",result); }else { return new CommonResult(444,"插入失败",null); } } @GetMapping("/payment/get/{id}") public CommonResult get(@PathVariable("id") Long id) { System.out.println(id+"********&*&*&*&*"); Payment payment = paymentService.getPayment(id); log.info("查询结果"+payment+"服务端口"+serverPort); if(payment!=null) { return new CommonResult(200,"查询数据成功",payment); }else { return new CommonResult(444,"没有该记录",null); } } }
80端口yml文件
server: port: 80 spring: application: name: cloud-order-service eureka: client: #表示是否将自己注册进EurekaServer默认为true。 register-with-eureka: true #是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡 fetchRegistry: true service-url: defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka # 集群版 # defaultZone: http://localhost:7001/eureka
80端口启动类
@Configuration public class ApplicationContextConfig { @Bean @LoadBalanced //使用@LoadBalanced注解赋予RestTemplate负载均衡的能力 public RestTemplate restTemplate() { return new RestTemplate(); } }
80端口业务类
@RestController @Slf4j public class orderController { // public static final String PaymentSrv_URL = "http://localhost:8001"; public static final String PAYMENT_SRV = "http://CLOUD-PAYMENT-SERVICE"; @Autowired private RestTemplate restTemplate; @GetMapping("/consumer/payment/create") //客户端用浏览器是get请求,但是底层实质发送post调用服务端8001 public CommonResult create(Payment payment) { System.out.println("**********"); return restTemplate.postForObject(PAYMENT_SRV + "/payment/create",payment,CommonResult.class); } @GetMapping("/consumer/payment/get/{id}") public CommonResult getPayment(@PathVariable Long id) { return restTemplate.getForObject(PAYMENT_SRV + "/payment/get/"+id, CommonResult.class, id); }
结果:
发送请求:http://localhost/consumer/payment/get/31
第一次:
第二次:
服务端口号为8001