springcloud组件
1、Eureka服务注册与发现
Eureka是一个基于REST的服务,用于定位服务,以实现云端中间层服务发现和故障转移,就可以访问到服务,而不需要修改调用的配置文件。
1.1、原理
Eureka包含两个组件:Eureka Server和Eureka Client。
- Eureka Server提供服务注册服务,各个节点启动后,会在EurekaServer中进行注册,这样Eureka Server中的服务注册表中将会出现所有可用的服务节点信息。
- Eureka Client是一个java客户端,用于剑豪EurekaServer的交互,客户点同时具备内置的轮询负载算法的负载均衡器。在应用启动后,将会向EurekaServer发送心跳(默认周期30秒)。如果EurekaServer在多个心跳周期没有收到某个节点的心跳,EurekaServer将会从服务注册表中把这个服务节点移除(默认周期W)
三大角色
- Eureka Server:提供服务的注册和发现
- Server Provider:将自身服务注册到Eureka中,从而使消费方能够找到
- Server Consumer:服务消息方从Eureka中获取注册服务列表,从而找到消费服务
1.2、构建微服务注册到EurekaServer
1.2.1、Eureka Server
启动类
@SpringBootApplication
@EnableEurekaServer
public class EurekaMain7001 {
public static void main(String[] args) {
SpringApplication.run(EurekaMain7001.class,args);
}
}
yml文件
server:
port: 7001
eureka:
instance:
hostname: localhost
client:
register-with-eureka: false
fetch-registry: false
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
1.2.2、Eureka Client 之服务提供方(支付微服务)
启动类
@SpringBootApplication
@EnableEurekaClient
public class PaymentMain8001 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain8001.class,args);
}
}
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
url: jdbc:mysql://192.168.75.128:3306/db2020?useUnicode=true&characterEncoding=utf-8&useSSL=false
username: root
password: root
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:7001/eureka
mybatis:
mapper-locations: classpath:mapper/*.xml
type-aliases-package: com.xc.springcloud.entities
1.2.3、Eureka Client 之服务消费方(订单微服务)
启动类:
@SpringBootApplication
@EnableEurekaClient
public class OrderMain80 {
public static void main(String[] args) {
SpringApplication.run(OrderMain80.class, args);
}
}
yml文件
server:
port: 80
spring:
application:
name: cloud-consumer-order
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:7001/eureka
启动三个微服务
http://localhost:7001/
没有EurekaServer本身是因为ym中配置了不将自己注册到服务注册中心。
1.3、Eureka集群原理(互相注册,互相守望)
1.3.1、Eureka集群搭建
本地搭建为了区分ip,做一些域名映射 本地模拟集群,创建两个Module项目 7001yml文件
server:
port: 7001
eureka:
instance:
hostname: eureka7001.com
client:
register-with-eureka: false
fetch-registry: false
service-url:
defaultZone: http://eureka7002.com:7002/eureka/
7002yml文件
server:
port: 7002
eureka:
instance:
hostname: eureka7002.com
client:
register-with-eureka: false
fetch-registry: false
service-url:
defaultZone: http://eureka7001.com:7001/eureka/
Eureka Server地址互相注册
1.3.2、支付和订单微服务注册到Eureka集群
订单微服务yml 支付微服务yml同上
1.3.2、支付微服务搭建集群
支付微服务(服务方) 订单服务8002和8001服务一样,服务名字都叫CLOUD-PAYMENT-SERVICE,只是端口号不一样。
订单微服务(消费方) 订单服务利用RestTemplate跨服务调用。订单微服务接口调用支付微服务接口
@Configuration
public class ApplicationConfig {
@Bean
@LoadBalanced
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
跨服务调用 订单服务(消费方)调用支付服务(服务提供方),支付服务已经注册到EurekaServer中,服务名为CLOUD-PAYMENT-SERVICE,已包含ip和端口,故可以写成 url = http://CLOUD-PAYMENT-SERVICE;
@RestController
@Slf4j
public class OrderController {
public static final String PAYMENT_URL = "http://CLOUD-PAYMENT-SERVICE";
@Resource
private RestTemplate restTemplate;
@GetMapping("/consumer/payment/create")
public CommonResult<Payment> create(Payment payment){
return restTemplate.postForObject(PAYMENT_URL+"/payment/create",payment,CommonResult.class);
}
@GetMapping("/consumer/payment/get/{id}")
public CommonResult<Payment> getPaymentById(@PathVariable Long id){
return restTemplate.getForObject(PAYMENT_URL + "/payment/get/" + id, CommonResult.class);
}
}
访问地址
http://localhost/consumer/payment/get/1
第一次 第二次 端口轮询交替,证明访问支付微服务8001和8002轮询交替发送请求
1.4、微服务信息完善
1.4.1、服务名称修改
修改yml文件
修改后
1.4.2、访问信息有ip信息提示
修改yml文件 修改后
2、服务发现Discovery
启动类
@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient
public class PaymentMain8001 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain8001.class,args);
}
}
@RestController
@Slf4j
public class PaymentController {
@Value("${server.port}")
private String serverPort;
@Resource
private DiscoveryClient discoveryClient;
@GetMapping("/payment/discovery")
public Object discovery(){
List<String> services = discoveryClient.getServices();
log.info("微服务名称:"+services.toString());
List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");
for (ServiceInstance instance : instances) {
log.info("微服务id:"+instance.getServiceId()+", ip:"+instance.getHost()+", 端口:"+instance.getPort()+", url: "+instance.getUri());
}
return this.discoveryClient;
}
}
访问地址
http://localhost:8001/payment/discovery
控制台结果
3、Eureka自我保护
为了防止EurekaClient可以正常运行,但是与Eureka网络不通情况下,EurekaServer不会like将EurekaClient服务剔除。
原则就是宁可保留错误的服务注册信息,也不盲目注销任何可能健康的服务实例。
出现一下这段话,则证明进入自我保护机制
3.1、禁止自我保护
EurekaServer EurekaClient
4、不同注册中心异同点
4.1、CAP原则
- C(Consistency)强一致性
- A(Avaiability)可用性
- P(Partiton tolerance)分区容错性
CAP核心理论,一个分布式系统不可能同时满足一致性,可用性,容错性这三个需求,由于分区容错性P在分布式中是必须保证的,因此只能在A和C之间权衡。
- Zookeeper/Consul 保证的是CP,满足数据一致性。(服务可用挂,数据不能错)
- Eureka 保证的AP,满足高可用,对数据一致性不是特别高。(服务不可挂,数据可以错)
- Eureka/Consul有图形界面,Zookeeper没有
|