本文共 23012 字,大约阅读时间需要 76 分钟。
博客参考学习视频: https://www.bilibili.com/video/BV18E411x7eT?from=search&seid=4388336378730572330
上一篇:
SpringCloud 封装了 Netflix 公司开发的 Eureka 模块来实现服务治理。 在传统的 RPC 远程调用框架中, 管理每个服务与服务之间依赖关系比较复杂, 所以需要使用服务治理管理服务与服务之间依赖关系, 了以实现服务调用、 负载均衡、容错等, 实现服务发现与注册 。
建Module
改POM
org.springframework.cloud spring-cloud-starter-netflix-eureka-server com.atguigu.springcloud cloud-api-common ${project.version} org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-actuator org.springframework.boot spring-boot-devtools runtime true org.projectlombok lombok true org.springframework.boot spring-boot-starter-test test
1.X 和 2.X 的对比说明
写 YML
server: port: 7001eureka: instance: hostname: localhost #eureka服务端的实例名称 client: register-with-eureka: false #false表示不向注册中心注册自己。 fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务 service-url: defaultZone: http://${ eureka.instance.hostname}:${ server.port}/eureka/
主启动
@SpringBootApplication@EnableEurekaServerpublic class EurekaMain7001 { public static void main(String[] args) { SpringApplication.run(EurekaMain7001.class, args); }}
注意
:需要在启动类上配置注解 @EnableEurekaServer,开启注册中心
测试
http://localhost:7001/ ,效果页面
改 POM ( cloud-provider-payment8001)
org.springframework.cloud spring-cloud-starter-netflix-eureka-client
1.X 和 2.X 的对比说明
写 YML
eureka: client: # 表示是否将自己注册进eurekaServer 默认为 true。 register-with-eureka: true # 是否从EureaServer 抓取已有的注册信息,默认为true.单节点无所谓,集群必须设置true才能配合ribbon使用负载均衡 fetchRegistry: true service-url: defaultZone: http://localhost:7001/eureka
主启动
@EnableEurekaClient@SpringBootApplicationpublic class PaymentMain8001 { public static void main(String[] args) { SpringApplication.run(PaymentMain8001.class, args); }}
添加:注解 @EnableEurekaClient
测试
改POM
org.springframework.cloud spring-cloud-starter-netflix-eureka-client
写 YML
spring: application: name: cloud-order-serviceeureka: client: register-with-eureka: true fetchRegistry: true service-url: defaultZone: http://localhost:7001/eureka
主启动 @EnableEurekaClient
@SpringBootApplication@EnableEurekaClientpublic class OrderMain80 { public static void main(String[] args) { SpringApplication.run(OrderMain80.class, args); }}
测试
BUG
**微服务RPC远程服务调用最核心的是什么 **
高可用
解决办法:搭建 Eureka 注册中心集群,实现负载均衡+故障容错
新建 cloud-eureka-server7002 和 POM
参考 cloud-eureka-server7001项目工程
修改映射配置
找到 C:\Windows\System32\drivers\etc 路径下的 hosts 文件
修改映射配置添加进 hosts 文件
写 YML
server: port: 7001eureka: instance: hostname: eureka7001.com #eureka服务端的实例名称 client: register-with-eureka: false #false表示不向注册中心注册自己。 fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务 service-url: defaultZone: http://eureka7002.com:7002/eureka/ #设置与 eureka server 交互的地址查询服务和注册服务都需要依赖这个地址
server: port: 7002eureka: instance: hostname: eureka7002.com #eureka服务端的实例名称 client: register-with-eureka: false #false表示不向注册中心注册自己。 fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务 service-url: defaultZone: http://eureka7001.com:7001/eureka/ #设置与 eureka server 交互的地址查询服务和注册服务都需要依赖这个地址
主启动类 (参考cloud-eureka-server7001 的主启动类 )
@SpringBootApplication@EnableEurekaServerpublic class EurekaMain7002 { public static void main(String[] args) { SpringApplication.run(EurekaMain7002.class, args); }}
YML
eureka: client: register-with-eureka: true fetch-registry: true service-url: defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka # 集群版
YML
eureka: client: register-with-eureka: true fetchRegistry: true service-url:# defaultZone: http://localhost:7001/eureka defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka #集群版
新建 cloud-provider-payment8002 和 POM
参考 cloud-provider-payment8001
写 YML
server: port: 8002spring: application: name: cloud-payment-service datasource: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/db2019?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC username: root password: 6090mybatis: mapperLocations: classpath:mapper/*.xml type-aliases-package: com.oy.springcloud.entities # 所有Entity别名类所在包eureka: client: register-with-eureka: true fetch-registry: true service-url: # 集群版 defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
主启动
@EnableEurekaClient@SpringBootApplicationpublic class PaymentMain8002 { public static void main(String[] args) { SpringApplication.run(PaymentMain8002.class, args); }}
业务类 直接从8001 粘贴
修改8001/8002的controller
@Value("${server.port}")private String serverPort;
Bug: 订单服务访问地址不能写死
原本:(cloud-consumer-order80)
更改:
public static final String PAYMENT_URL = "http://CLOUD-PAYMENT-SERVICE";
使用@LoadBalanced注解赋予RestTemplate负载均衡的能力 (cloud-consumer-order80)
修改YML (cloud-provider-payment8001) 部分
instance: instance-id: payment8001
效果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3LshZHHm-1602487784697)(C:\Users\hp\AppData\Roaming\Typora\typora-user-images\image-20201009230616274.png)]
当前问题:没有ip提示
修改 cloud-provider-payment8001 YML部分
prefer-ip-address: true
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sRGagkv0-1602487784698)(C:\Users\hp\AppData\Roaming\Typora\typora-user-images\image-20201009230941130.png)]
效果:
@Resourceprivate DiscoveryClient discoveryClient;@GetMapping(value = "/payment/discovery")public Object discovery(){ Listservices = discoveryClient.getServices(); for (String element : services) { log.info("**** element:"+ element); } 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
@EnableEurekaClient@EnableDiscoveryClient // 服务发现@SpringBootApplicationpublic class PaymentMain8001 { public static void main(String[] args) { SpringApplication.run(PaymentMain8001.class, args); }}
先启动 EurekaServer, 7001/7002 服务,再启动 8001 主启动类,需要稍等一会
http://localhost:8001/payment/discovery
总结
:某时刻某一个微服务不可用了,Eureka 不会立即清理,依旧会对该服务的信息进行保存,属于CAP 里的 AP分支
注册中心 eureakeServer 端 7001: 出 厂 默 认 , 自 我 保 护 机 制 是 开 启的:eureka.server.enable-self-preservation = true
使用 eureka.server.enable-self-preservation = false 可以禁用自我保护模式
在 eurekaServer 端 7001 处设置关闭自我保护机制
效果图:
生产者客户端 eureakeClient 端 8001
默认:
eureka.instance.lease-renewal-interval-in-seconds=30 单位为秒( 默认是 30 秒)eureka.instance.lease-expiration-duration-in-seconds=90 单 位 为 秒( 默认是 90 秒)
配置:
instance: instance-id: payment8001 prefer-ip-address: true #Eureka客户端向服务端发送心跳的时间间隔,单位为秒(默认是30秒) lease-renewal-interval-in-seconds: 1 #Eureka服务端在收到最后一次心跳后等待时间上限,单位为秒(默认是90秒),超时将剔除服务 lease-expiration-duration-in-seconds: 2
https://github.com/Netflix/eureka/wiki
使用docker 快速创建 zookeeper 容器
CentOS 7 关闭防火墙指令
// 查看当前防火墙状态如果防火墙处于开启状态,firewalld.service前面的点是高亮的,Active:active(开启))systemctl status firewalld.service//关闭当前的防火墙(仅对本次开机有效,重启后防火墙会再次启用)systemctl stop firewalld.service//永久关闭防火墙(重启后防火墙依然关闭)systemctl disable firewalld.service// 启动防火墙 systemctl start firewalld
新建 cloud-provider-payment8004
POM
clould com.oy 1.0-SNAPSHOT 4.0.0 cloud-provider-payment8004 Zookeeper服务提供者 com.oy cloud-api-commons ${project.version} org.springframework.boot spring-boot-starter-web org.springframework.cloud spring-cloud-starter-zookeeper-discovery org.springframework.boot spring-boot-starter-actuator org.springframework.boot spring-boot-devtools runtime true org.projectlombok lombok true org.springframework.boot spring-boot-starter-test test
YML
server: # 8004表示注册到zookeeper服务器的支付服务提供者端口号 port: 8004spring: application: # 服务别名---注册zookeeper到注册中心的名称 name: cloud-provider-payment cloud: zookeeper: connect-string: 116.63.177.72:2181
主启动类
import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.client.discovery.EnableDiscoveryClient;@EnableDiscoveryClient@SpringBootApplicationpublic class PaymentMain8004 { public static void main(String[] args) { SpringApplication.run(PaymentMain8004.class, args); }}
Controller
@RestController@Slf4jpublic class PaymentController { @Value("${server.port}") private String serverPort; @GetMapping(value = "/payment/zk") public String paymentzk(){ return "springcloud with zookeeper:"+serverPort+"\t"+ UUID.randomUUID().toString(); }}
启动 8004 注册进 zookeeper
注意
:启动后问题存在下面问题
Why:
cloud2020 com.atguigu.springcloud 1.0-SNAPSHOT 4.0.0 cloud-provider-payment8004 Zookeeper服务提供者 org.springframework.cloud spring-cloud-starter-zookeeper-discovery org.apache.zookeeper zookeeper org.apache.zookeeper zookeeper 3.4.9 org.springframework.boot spring-boot-starter-actuator org.springframework.boot spring-boot-devtools runtime true org.projectlombok lombok true org.springframework.boot spring-boot-starter-test test
测试
获得 json 串后用在线工具查看试试 (dokcer 容器)
思考: 服务节点是临时节点还是持久节点——是临时节点
新建 cloud-consumerzk-order80
POM
cloud2020 com.atguigu.springcloud 1.0-SNAPSHOT 4.0.0 cloud-consumerzk-order80 com.atguigu.springcloud cloud-api-common ${project.version} org.springframework.boot spring-boot-starter-web org.springframework.cloud spring-cloud-starter-zookeeper-discovery org.apache.zookeeper zookeeper org.apache.zookeeper zookeeper 3.4.9 org.springframework.boot spring-boot-starter-actuator org.springframework.boot spring-boot-devtools runtime true org.projectlombok lombok true org.springframework.boot spring-boot-starter-test test
YML
server: port: 80spring: application: # 服务别名 name: cloud-consumer-order cloud: zookeeper: # 注册到zookeeper地址 connect-string: localhost:2181
主启动
@SpringBootApplication@EnableDiscoveryClientpublic class OrderZkMain80 { public static void main(String[] args) { SpringApplication.run(OrderZkMain80.class, args); }}
主业务类
package com.springcloud.config;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.client.RestTemplate;/** * @Author OY * @Date 2020/10/10 */@Configurationpublic class ApplicationContextConfig { @Bean public RestTemplate restTemplate(){ return restTemplate(); }}
package com.springcloud.controller;import lombok.extern.slf4j.Slf4j;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.client.RestTemplate;import javax.annotation.Resource;/** * @Author OY * @Date 2020/10/10 */@RestController@Slf4jpublic class OrderZkController { @Resource private RestTemplate restTemplate; public static final String INVOKE_URL = "http://cloud-provider-payment"; @GetMapping("/consumer/payment/zk") public String paymentInfo() { return restTemplate.getForObject(INVOKE_URL + "/payment/zk", String.class); }}
验证测试
访问测试地址
http://localhost/consumer/payment/zk
https://www.consul.io/downloads.html
https://www.springcloud.cc/spring-cloud-consul.html
https://learn.hashicorp.com/consul/getting-started/install.html
consul agent -dev
通过以下地址可以访问 Consul 的首页:http://localhost:8500/
新 建 Module 支 付 服 务 provider8006
cloud-providerconsul-payment8006
POM
clould com.oy 1.0-SNAPSHOT 4.0.0 cloud-providerconsul-payment8006 org.springframework.cloud spring-cloud-starter-consul-discovery com.oy cloud-api-commons 1.0-SNAPSHOT org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-actuator org.springframework.boot spring-boot-devtools runtime true org.projectlombok lombok true org.springframework.boot spring-boot-starter-test test
YML
server: port: 8006spring: application: name: consul-provider-payment cloud: consul: host: localhost port: 8500 discovery: service-name: ${ spring.application.name}
主启动类
@EnableDiscoveryClient@SpringBootApplicationpublic class PaymentMain8006 { public static void main(String[] args) { SpringApplication.run(PaymentMain8006.class, args); }}
主业务类 Controller
@RestController@Slf4jpublic class PaymentController { @Value("${server.port}") private String serverPort; @GetMapping(value = "/payment/consul") public String paymentConsul(){ return "SpringCloud with consul:" + serverPort + "\t"+ UUID.randomUUID().toString(); }}
验证测试
http://localhost:8006/payment/consul
新 建 Module 消 费 服 务 order8006
cloud-consumerconsul-order80
POM
clould com.oy 1.0-SNAPSHOT 4.0.0 cloud-consumerconsul-order80 org.springframework.cloud spring-cloud-starter-consul-discovery com.oy cloud-api-commons 1.0-SNAPSHOT org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-actuator org.springframework.boot spring-boot-devtools runtime true org.projectlombok lombok true org.springframework.boot spring-boot-starter-test test
YML
server: port: 80spring: application: name: consul-consumer-order cloud: consul: host: localhost port: 8500 discovery: service-name: ${ spring.application.name}
主启动类
package com.oy.springcloud;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.client.discovery.EnableDiscoveryClient;@SpringBootApplication@EnableDiscoveryClientpublic class OrderConsulMain80 { public static void main(String[] args) { SpringApplication.run(OrderConsulMain80.class, args); }}
配置Bean
package com.oy.springcloud.config;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;@Configurationpublic class ApplicationConfig { @LoadBalanced // 负载均衡 @Bean public RestTemplate restTemplate(){ return new RestTemplate(); }}
Controller
package com.oy.springcloud.controller;import lombok.extern.slf4j.Slf4j;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.client.RestTemplate;import javax.annotation.Resource;/** * @Author OY * @Date 2020/10/11 */@RestController@Slf4jpublic class OrderConsulController { public static final String INVOME_URL = "http://consul-provider-payment"; @Resource public RestTemplate restTemplate; @GetMapping("/consumer/payment/consul") public String payment(){ String result = restTemplate.getForObject(INVOME_URL+"/payment/consul",String.class ); return result; }}
验证测试
访问测试地址:http://localhost/consumer/payment/consul
CAP 理论关注粒度是数据, 而不是整体系统设计的策略
AP(Eureka) 架构
当网络分区出现后,为了保证可用性,系统B可以返回值,保证系统的可用性。
结论
:违背了一致性C的要求,只满足可用性和分区容错,即AP
如果有帮助的话动动小手,留个赞呗!!!CP(Zookeeper/Consul) 架构
转载地址:http://exbki.baihongyu.com/