项目文件链接
eureka集群搭建
首先我的项目结构如下
server7001
server7002
server7003
user
order
oder2
money
money2
三台server组成eureka集群
用户模块调用微服务order和money
server7000的配置如下
server:
port: 7000
eureka:
server:
enable-self-preservation: false
eviction-interval-timer-in-ms: 4000
instance:
hostname: server7000
client:
#registerWithEureka: false
#fetchRegistry: false
serviceUrl:
defaultZone: http://server7001:7001/eureka,http://server7002:7002/eureka
修改hosts文件,路径为C:\Windows\System32\drivers\etc,添加如下三行
127.0.0.1 server7000
127.0.0.1 server7001
127.0.0.1 server7002
其他两个server的配置基本一致,另外在启动类加上@EnableEurekaServer,就可以启动三台eureka服务了
order的配置如下
# 服务名称
spring:
application:
name: lry-spring-cloud-eureka-order
# 服务端口号
server:
port: 9000
#Eureka 相关配置
eureka:
instance:
prefer-ip-address: true
client:
service-url:
#defaultZone: http://localhost:9999/eureka/ #单机
defaultZone: http://server7000:7000/eureka,http://server7001:7001/eureka,http://server7002:7002/eureka
money的配置如下
# 服务名称
spring:
application:
name: lry-spring-cloud-eureka-money
# 服务端口号
server:
port: 8888
#Eureka 相关配置
eureka:
instance:
prefer-ip-address: true
client:
service-url:
#defaultZone: http://localhost:9999/eureka/ #单机
defaultZone: http://server7000:7000/eureka,http://server7001:7001/eureka,http://server7002:7002/eureka
user的配置如下
# 服务名称
spring:
application:
name: lry-spring-cloud-eureka-user
# 服务端口号
server:
port: 8081
#Eureka 相关配置
eureka:
instance:
prefer-ip-address: true
client:
service-url:
#defaultZone: http://localhost:9999/eureka/ #单机
defaultZone: http://server7000:7000/eureka,http://server7001:7001/eureka,http://server7002:7002/eureka
5个client 端的启动类加上@EnableEurekaClient
ribbon
user模块的appConfig加入
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
//这个可以不写,有默认的负载均衡算法
@Bean
public IRule rule(){
return new RandomRule();
}
ribbon负载均衡调用order微服务
@Autowired
private RestTemplate restTemplate;
@RequestMapping("queryOrder")
public String queryOrder(){
ResponseEntity<String> res = restTemplate.getForEntity("http://lry-spring-cloud-eureka-order/order",String.class);
return res.getBody();
}
如果user模块想使用A负载均衡算法调用order,使用B算法调用money,可以使用如下办法:
写两个config文件
@Configuration
public class MoneyRuleConfig {
@Bean
public IRule rule(){
return new RoundRobinRule();
}
}
@Configuration
public class OrderRuleConfig {
@Bean
public IRule rule(){
return new RandomRule();
}
}
但是注意这两个config必须在启动类UserApplication所在包的外面,也就是compontScan包外面
启动类上加上即可
@RibbonClients({
@RibbonClient(name = "lry-spring-cloud-eureka-money",configuration = MoneyRuleConfig.class),
@RibbonClient(name = "lry-spring-cloud-eureka-order",configuration = OrderRuleConfig.class),
})
feign
启动类加上@EnableFeignClients
写两个接口
@FeignClient(name = "lry-spring-cloud-eureka-money")
public interface MoneyService {
@RequestMapping("money")
String queryMoney();
}
@FeignClient(name = "lry-spring-cloud-eureka-order")
public interface OrderService {
@RequestMapping("order")
String queryOrder();
}
调用方式
@Autowired
private OrderService orderService;
@Autowired
private MoneyService moneyService;
@RequestMapping("queryFeignOrder")
public String queryFeignOrder(){
return orderService.queryOrder();
}
@RequestMapping("queryFeignMoney")
public String queryFeignOMoney(){
return moneyService.queryMoney();
}
CAP定理
分布式系统有三个指标
Consistency —一致性
Availability —可用性
Partition tolerance —分区容错性
CAP定理:CAP不可能同时做到,要么CP,要么AP
解释CAP为什么不能同时做到?
分区容错性:S1 和 S2 是两台跨区的服务器。S1 向 S2 发送一条消息,S2 可能无法收到。系统设计的时候,必须考虑到这种情况。也就是说P是必须要的,那么就是说A,C只能选一个
保证C,客户向节点1写入一个数据,锁住集群,同步信息,但是可用性就降低了
保证A,客户向节点1写入一个数据,再去其他节点读取数据,就无法保证一致性
对于ap和cp如何选择?
对于数据一致性要求很高的例如银行业务选cp
对于业务可用性要求很高例如双十一选ap
二者也可以切换,在双十一高峰期选ap,高峰期过后选cp
zookeeper和eureka
zookeeper是主从式的集群,要选举leader花费时间,所以肯定式CP
Eureka在设计的时候遵循的是AP原则,即可用性。Eureka各个节点(服务)是平等的, 没有主从之分,几个节点
down掉不会影响正常工作,剩余的节点(服务) 依然可以提供注册与查询服务,而Eureka的客户端在向某个
Eureka注册或发现连接失败,则会自动切换到其他节点,也就是说,只要有一台Eureka还在,就能注册可用(保
证可用性), 只不过查询到的信息不是最新的(不保证强一致),除此之外,Eureka还有自我保护机制,如果在
15分钟内超过85%节点都没有正常心跳,那么eureka就认为客户端与注册中心出现了网络故障,此时会出现一下
情况:
1: Eureka 不再从注册列表中移除因为长时间没有收到心跳而过期的服务。
2:Eureka 仍然能够接收新服务的注册和查询请求,但是不会被同步到其它节点上(即保证当前节点可用)
3: 当网络稳定后,当前实例新的注册信息会被同步到其它节点中