spring boot学习小结Ⅰ
- 问题如下:
1. eureka微服务创建的流程
1.1 什么是Eureka?
- Eureka是服务注册中心,也可以是一个集群。他对外暴露自己的地址。
- Eureka包含两个组件,EurekaServer和EurekaClient。
- 其中,EurekaServer负责提供服务注册服务,EurekaClient则是通过注册中心进行访问。
1.2 eureka微服务创建流程
- ① 构建server模块
- 引入pom依赖
<!--eureka依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
- ② 编写
application.yml
配置文件
server:
port: 7001
eureka:
instance:
hostname: localhost # eureka 服务器的实例名称 127.0.0.1
client:
# false 代表不向服务注册中心注册自己,因为它本身就是服务中心
register-with-eureka: false
# false 代表自己就是服务注册中心,自己的作用就是维护服务实例,并不需要去检索服务
fetch-registry: false
service-url:
# 设置与 Eureka Server 交互的地址,查询服务 和 注册服务都依赖这个地址
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
- ③ 编写启动类
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)// exclude :启动时不启用 DataSource的自动配置检查
@EnableEurekaServer // 标识开启Eureka服务
public class EurekaApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class,args);
}
}
- ④ 启动测试,查看是否搭建成功
- 访问7001端口
http://localhost:7001
1.3 项目中使用
① 服务提供方搭建
- pom.xml文件中引入eureka的client包依赖
<!--eureka-client-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
- 服务提供方启动类 使用注解:
@EnableEurekaClient // 标识开启Eureka服务
- 同时,配置文件中添加Eureka配置项
eureka:
client:
# 注册进 Eureka 的服务中心
register-with-eureka: true
# 检索 服务中心 的其它服务
fetch-registry: true
service-url:
# 设置与 Eureka Server 交互的地址
defaultZone: http://localhost:7001/eureka/
- 启动服务提供方启动器,查看是否成功
② 服务消费方搭建(服务消费方搭建与服务提供方相同)
- pom.xml文件中添加Eureka依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
- 服务消费方启动类使用注解:
@EnableEurekaClient
- 服务消费方配置文件添加Eureka相关配置项
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:7001/eureka/
spring:
application:
name: cloud-consumer-order80
- 服务消费方,启动测试
2. 搭建Eureka集群
2.1 为什么要使用集群
- EurekaServer是服务的注册中心。但,若只有一个EurekaServer,一旦这个EurekaServer停止或出现问题,整个应用就会被影响。
- EurekaServer同时也可以是一个集群,也就是说,它本身可形成高可用的Eureka中心。因此,当一个EurekaServer出现问题后,还有其他备用选项,不会出现影响整个应用的情况。
- Eureka集群原理:相互注册,互相守望。
2.2 搭建步骤
以两个EurekaServer为例。
- 为了模拟多个EurekaServer在不同的机器上。因此,可通过进入
C:\Windows\System32\drivers\etc
下的hosts文件中进行修改相关配置。
- 搭建两个server模块
- 步骤,同上创建server模块
- 两个配置文件分别添加Eureka相关配置
- 两个server的端口号不能相同
server:
port: 7001
eureka:
instance:
hostname: eureka7001.com # eureka 服务器的实例名称
client:
# false 代表不向服务注册中心注册自己,因为它本身就是服务中心
register-with-eureka: false
# false 代表自己就是服务注册中心,自己的作用就是维护服务实例,并不需要去检索服务
fetch-registry: false
service-url:
#一定要注意这里的地址,这是搭建集群的关键
defaultZone: http://eureka7002.com:7002/eureka/
server:
port: 7002
eureka:
instance:
hostname: eureka7002.com # eureka 服务器的实例名称
client:
# false 代表不向服务注册中心注册自己,因为它本身就是服务中心
register-with-eureka: false
# false 代表自己就是服务注册中心,自己的作用就是维护服务实例,并不需要去检索服务
fetch-registry: false
service-url:
# 设置与 Eureka Server 交互的地址,查询服务 和 注册服务都依赖这个地址
defaultZone: http://eureka7001.com:7001/eureka/
- 分别启动两个server模块的启动类,查看结果
- 但是,eureka.instance.hostname 才是server的注册的地址。它代表了server指向了其他server。
- 因此,通过它,可实现EurekaServer相关注册,实现集群。
2.2.1 改进
- 修改两个server模块的相关配置。
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/
- 启动测试(前提:两个eureka都启动)
3. 搭建服务提供方集群
-
服务提供方是提供者,在整个项目中,为了保证集群的有效性,服务提供方也需要搭建服务提供方集群。
-
步骤:
-
构建服务提供方模块(以两个服务提供方模块为例)
-
两个服务提供方中Eureka依赖
-
配置两个application.yml配置文件
- 注意:两个配置文件中的port不能相同
- 修改EurekaServer的交互地址:
defaultZone: http://localhost:7001/eureka/,http://eureka7002.com:7002/eureka/
-
编写启动类,并启动测试。
- 启动类中添加两个注解
@MapperScan("xxxxx")// 扫描包
@EnableEurekaClient // 标识开启eureka客户端
- 测试结果:
3.1 搭建服务消费方集群
- 原因:
- 如果服务提供方做了集群,使用时,服务消费方怎么判断去访问哪一个服务提供方?
- 同时,服务消费方调用服务提供方时,是通过url调用的,因此,url不能写死。
- 搭建服务消费方集群步骤与搭建服务提供方集群步骤相同
- 注意:服务消费方使用了RestTemplate,因此,在controller中使用时,只需要修改远程调用的地址url为服务提供方的
application.name
值(微服务名称)。 - 同时,RestTemplate模板中使用注解
@LoadBalanced
作用:对服务提供方进行负载均衡调用,避免出现找不到对应的服务名称,造成服务消费方不清楚调用哪个服务提供方,应用使用出错。
- 注意:服务消费方使用了RestTemplate,因此,在controller中使用时,只需要修改远程调用的地址url为服务提供方的
4. RestTemplate的使用
RestTemplate
用来进行服务调用- 使用时,需要在spring容器中注入RestTemplate
- 具体如下:
@Configuration
public class ApplicationContextConfig {
@Bean
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
//相当于<bean id="getRestTemplate" class="org.springframework.web.client.RestTemplate"></bean>
- 使用时,在controller中通过注解
@AutoWired
引入RestTemplate模板。例如:
@RestController
@Slf4j
public class OrderController {
@Autowired
private RestTemplate restTemplate;
//远程调用的 地址
public static final String PAYMENY_URL = "http://localhost:8001";
@GetMapping("consumer/payment/{id}")
public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id){
return restTemplate.getForObject(PAYMENY_URL + "/payment/" + id, CommonResult.class);
}
}
5. 什么是CAP?
-
CAP理论:
- 解决分布式系统各个节点的状态无法保持一致。(处理数据一致性问题是必须要考虑的问题。)
- CAP:
- Consistency,一致性。对于客户端每次读操作,要么读到最新数据,要么读取失败。
- Availability,可用性。任何客户端的请求都能得到相应的数据,不会出现相应错误。
- Partition tolerance,分区容忍性。分布式系统通过网络进行通信,网络是不可靠的。当任意数量的消息丢失或延迟达到时,系统仍会继续提供服务,不会挂掉。
- 但,一个分布式系统,不能同时做到这三点。即,出现CA,CP,AP三种情况。
-
CP 和 AP
- CP
- 如果不要求可用性,相当于每个请求都需要在各服务器之间强一致,而分区容错性可能会导致同步时间无限延长,因此CP 也是可以保证的。
- AP
- 如果要可用性高并允许分区,则需放弃一致性。一旦分区发生故障,节点之间可能会失去联系,为了实现高可用,每个节点只能用本地数据提供服务,而这样会导致全局数据的不一致性。
- CAP取舍
- CP:优先保证一致性和分区容错性,放弃可用性。在数据一致性要求比较高的场合(譬如:zookeeper,Hbase,PXC) 是比较常见的做法,一旦发生网络故障或者消息丢失,就会牺牲用户体验,等恢复之后用户才逐渐能访问。
- AP:优先保证可用性和分区容错性,放弃一致性。跟CP一样,放弃一致性不是说一致性就不保证了,而是逐渐的变得一致。
- CA:优先保证一致性和可用性,放弃分区容错性。 相当于放弃系统的扩展性,系统不再是分布式的,不符合分布式系统设计的初衷。
- CP
6. eureka的自我保护模式?如何配置?
- eureka自我保护机制:
- 如果在15分钟内超过85%的节点都没有正常的心跳,那么Eureka就认为客户端与注册中心出现了网络故障,所以不会再接收心跳,也不会删除服务。
- eureka自我保护机制配置:
eureka:
server:
# 关闭自我保护机制
enable-self-preservation: false # 为true 则表示打开自我保护机制
eviction-interval-timer-in-ms: 2000
7. eureka 和zookeeper consul的区别
- Eureka:AP原则,无主从节点,一个节点挂了,自动切换其他节点可以使用,去中心化。
- Zookeeper和Consul :CP设计,保证了一致性,集群搭建的时候,某个节点失效,则会进行选举行的leader,或者半数以上节点不可用,则无法提供服务,因此可用性没法满足。
- Eureka保证了可用性,牺牲了一致性。
- Consul保证了一致性,牺牲了可用性。
8. 使用ribbon进行负载均衡的步骤
- 由于eureka中的依赖集成了ribbon,不需要单独引入。
- 在服务消费方使用
@LoadBalanced
注解开启负载均衡。 - Ribbon工作时,分成两步:
- 先选择EurekaServer,会优先选择同一个区域内负载较少的server。
- 再根据用户指定的Ribbon提供的策略,从server取到的服务注册列表中选择一个远程url。
- Ribbon提供了多种策略:轮询,随机和根据相应时间加权。
- 使用注解
@RibbonClient(name="微服务名称",configuration=自定义配置类.class)
指定访问哪个服务,使用何种负载均衡的算法访问。
9. ribbon负载均衡的策略
- 轮询策略:RoundRobinRule
- 随机策略:RandomRule
- 可用过滤策略:AvailabilityFilteringRule
- 响应时间权重策略:WeightedResponseTimeRule
- 轮询失败重试策略:RetryRule
- 并发量最小可用策略:BestAvailableRule
- 默认规则:ZoneAvoidanceRule
10. 如何开启自定义负载均衡
- 主启动类添加注解:
@RibbonClient(name="微服务名称",configuration=自定义规则.class)
- 自定义规则配置
- 此配置类不能放在
@ComponentScan
所扫描的当前包下以及子包下,否则自定义配置类就会被所有Ribbon客户端共享,达不到特殊化定制目的. - 代码如下:
- 此配置类不能放在
/**
* 自定义规则
*/
@Configuration
public class MyRuleConfig {
@Bean
public IRule myselfRule() {
// 指定策略:我们自定义的策略
return new RandomRule();
}
}
- 实现自定义策略。
- 实现AbstractLoadBalancerRule类
- 重写choose方法