# StudyMiniService
**Repository Path**: yang1yu/study-mini-service
## Basic Information
- **Project Name**: StudyMiniService
- **Description**: record my study of my MiniService
- **Primary Language**: Java
- **License**: Apache-2.0
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2022-08-25
- **Last Updated**: 2022-09-22
## Categories & Tags
**Categories**: Uncategorized
**Tags**: Eureka, openfeign, Gateway
## README
### 微服务
### 1.Cloud各种组件
- 注册中心
- **Nacos**
- Consul
- ZooKepper
- 服务调用
- **OpenFegin**
- LoadBalancer
- **Riboon**
- 服务降级
- **sentinel**
- 服务网关
- **gateway**
- 服务总线
- **nacos**
### 2.微服务架构编码构建
1. 构建父工程
New project -> 聚合总父工程名字->Maven选版本->工程名字->字符编码->注解生效激活->Java编码版本8->Filetype过滤
2. 父工程的POM文件
```xml
com.yy.springcloud
cloud2020
1.0-SNAPSHOT
UTF-8
1.8
1.8
4.12
1.2.17
1.16.18
5.1.47
1.1.16
```
3. Rest微服务工程构建
在父工程下面建立module,继承父工程,改pom、写yml、启动类、业务类、测试。
### 3.Eureka服务注册与发现
#### 3.1服务治理
在传统的rpc远程调用框架中,管理每个服务与服务之间依赖关系比较复杂,管理比较复杂,所以需要使用服务治理,管理服务于服务之间依赖关系,可以实现服务调用、负载均衡、容错等,实现服务发现与注册。
#### 3.2服务注册与发现
Eureka采用了CS的设计架构,Eureka Server 作为服务注册功能的服务器,它是服务注册中心。而系统中的其他微服务,使用 Eureka的客户端连接到 Eureka Server并维持心跳连接。这样系统的维护人员就可以通过 Eureka Server 来监控系统中各个微服务是否正常运行。

#### 3.3Eureka的两个组件
- Eureka Server提供服务注册服务
各个微服务节点通过配置启动后,会在EurekaServer中进行注册,这样EurekaServer中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观看到。
- EurekaClient通过注册中心进行访问
是一个Java客户端,用于简化Eureka Server的交互,客户端同时也具备一个内置的、使用轮询(round-robin)负载算法的负载均衡器。在应用启动后,将会向Eureka Server发送心跳(默认周期为30秒)。如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,EurekaServer将会从服务注册表中把这个服务节点移除(默认90秒)
```xml
依赖文件
org.springframework.cloud
spring-cloud-starter-netflix-eureka-server
2.1.2.RELEASE
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
```
单机配置如下:
yml文件配置:
```yaml
eureka的Client:
eureka:
client:
#是否将自己注册进EurekaServer 默认为True
register-with-eureka: true
#是否从EurekaServer抓取已有的注册信息,默认true ,集群必须设置true才能配合ribbon使用负载均衡
fetch-registry: true
service-url:
defaultZone: http://localhost:7001/eureka
eureka的Server:
server:
port: 7001
eureka:
instance:
#eureka服务端的实例名称
hostname: localhost
client:
#false不向注册中心注册自己
register-with-eureka: false
#false表示自己端就是注册中心,维护服务实例,不需要去检索服务
fetch-registry: false
service-url:
#设置与Eureka server交互的地址查询服务和注册服务都需要依赖这个地址
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
```
EurekaServer启动类:
```java
@EnableEurekaServer
public class EurekaMain7001
{
public static void main( String[] args )
{
SpringApplication.run(EurekaMain7001.class,args);
}
}
```
EurekaClient启动类:
```java
@EnableEurekaClient
public class OrderMain80 {
public static void main(String[] args) {
SpringApplication.run(OrderMain80.class,args);
}
}
```
启动成功之后为(http://localhost:7001):

#### 3.4Eureka集群
目的:高可用、负载均衡
互相注册,相互守望
集群配置如下:
1. 需要修改hosts(C:\Windows\System32\drivers\etc\hosts)的配置文件添加127.0.0.1 eureka7001.com 和127.0.0.1 eureka7002.com
2. 在7001上面注册7002,在7002上面注册7001
EurekaServer7001:
yml配置文件:
```yaml
server:
port: 7001
eureka:
instance:
#eureka服务端的实例名称
hostname: eureka7001.com
client:
#false不向注册中心注册自己
register-with-eureka: false
#false表示自己端就是注册中心,维护服务实例,不需要去检索服务
fetch-registry: false
service-url:
#设置与Eureka server交互的地址查询服务和注册服务都需要依赖这个地址
defaultZone: http://eureka7002.com:7002/eureka
```
EurekaServer7002:
yml配置:
```yaml
server:
port: 7002
eureka:
instance:
hostname: eureka7002.com #eureka服务端的实例名称
client:
fetch-registry: true
register-with-eureka: true
service-url:
defaultZone: http://eureka7001.com:7001/eureka/
```
在7001中有7002,类似7002中也有7001

在EurekaClient中,需要将EurekaServer的url添加到defaultZone中,用","隔开
```yaml
eureka:
client:
service-url:
defaultZone: http://eureka7002.com:7002/eureka,http://eureka7001.com:7001/eureka
register-with-eureka: true
fetch-registry: true
```

可以看到7001和7002已经集群成功,而且两个微服务也分别在eureka中可以看到
#### 3.5支付微服务集群
两个模块分别是:cloud-provider-server8001和cloud-provider-server8002
两个模块在Spring中的名称是一样的,如下图:

修改配置文件:
cloud-provider-server8001的yml文件为:
```yml
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://yang1yu.site:3306/springcloud?useSSL=false
password: yang1yu
username: root
type: com.alibaba.druid.pool.DruidDataSource
application:
#进入注册中心后的名称
name: cloud-payment-service
server:
port: 8001
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
eureka:
client:
#是否将自己注册进EurekaServer 默认为True
register-with-eureka: true
#是否从EurekaServer抓取已有的注册信息,默认true ,集群必须设置true才能配合ribbon使用负载均衡
fetch-registry: true
service-url:
defaultZone: http://eureka7002.com:7002/eureka,http://eureka7001.com:7001/eureka
```
cloud-provider-server8002的yml配置文件为:
```yml
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://yang1yu.site:3306/springcloud?useSSL=false
password: yang1yu
username: root
type: com.alibaba.druid.pool.DruidDataSource
application:
#进入注册中心后的名称
name: cloud-payment-service
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
eureka:
client:
#是否将自己注册进EurekaServer 默认为True
register-with-eureka: true
#是否从EurekaServer抓取已有的注册信息,默认true ,集群必须设置true才能配合ribbon使用负载均衡
fetch-registry: true
service-url:
defaultZone: http://eureka7002.com:7002/eureka,http://eureka7001.com:7001/eureka
server:
port: 8002
```
在cloud-consumer-order80中需要修改直接的请求路径,并使用restTemplate中自带的负载均衡来实现。
cloud-consumer-order80的controller:
```java
public class OrderController {
// public static final String URL = "http://localhost:8001";
// 服务地址去eureka中粘贴过来
public static final String URL = "http://CLOUD-PAYMENT-SERVICE";
@Autowired
private RestTemplate restTemplate;
@GetMapping("get")
public CommonResult get(){
return restTemplate.getForObject(URL+"/payment/get",CommonResult.class);
}
}
```
添加负载均衡在restTempla中添加(@LoadBalanced ):
```java
@Configuration
public class ApplicationContextConfig {
@Bean
@LoadBalanced //默认自带的负载均衡 CLOUD-PAYMENT-SERVICE
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
```
#### 3.6actuator微服务信息完善
主机名称:服务名称修改
在yml中添加如下:
```yml
eureka:
client:
# 服务名称修改actuator
instance:
instance-id: payment8001
```

访问信息有IP信息提示:
```yml
eureka:
client:
# 服务名称修改actuator
instance:
instance-id: payment8001
#访问信息有IP提示
prefer-ip-address: true
```
左下角会出现IP信息提示:

#### 3.7服务发现Discovery
对注册到eureka中的服务,可以通过服务发现来获取该服务的信息
需要在主启动类中添加注解:@EnableDiscoveryClient
还需要自动配置 DiscoveryClient
```java
@Autowired
// springcloud中的服务发现
private DiscoveryClient discoveryClient;
```
#### 3.8Eureka保护模式
保护模式主要用于一组客户端和Eureka Server之间存在网络分区场景下的保护,一旦进入保护模式。
EurekaServer将会尝试保护其服务注册表中的信息,**不再删除服务注册表中的数据,也就是不会注销任何微服务。**
目的:防止当网络分区故障发生时(延时、卡顿、拥挤)时,微服务与EurekaServer之间无法正常通信时误删了微服务。
**禁止自我保护**:
EurekaServer配置文件:
```yml
server:
port: 7001
eureka:
instance:
#eureka服务端的实例名称
hostname: eureka7001.com
client:
#false不向注册中心注册自己
register-with-eureka: false
#false表示自己端就是注册中心,维护服务实例,不需要去检索服务
fetch-registry: false
service-url:
#设置与Eureka server交互的地址查询服务和注册服务都需要依赖这个地址
defaultZone: http://eureka7002.com:7002/eureka
#关闭自我保护,保证不可用服务被删除
server:
enable-self-preservation: false
eviction-interval-timer-in-ms: 2000
```
EurekaClient配置文件:
```yml
eureka:
client:
#是否将自己注册进EurekaServer 默认为True
register-with-eureka: true
#是否从EurekaServer抓取已有的注册信息,默认true ,集群必须设置true才能配合ribbon使用负载均衡
fetch-registry: true
service-url:
defaultZone: http://eureka7002.com:7002/eureka,http://eureka7001.com:7001/eureka
#配置actuator
instance:
instance-id: payment8001
prefer-ip-address: true
#Eureka客户端向服务端发送心跳的时间间隔,单位秒默认30s
lease-renewal-interval-in-seconds: 1
#Eureka服务端在收到最后一次心跳后等待时间上限,单位为秒,超市将删除服务
lease-expiration-duration-in-seconds: 2
```
### 4.Openfeign服务接口调用
#### 4.1概述
**创建一个微服务接口并且在接口上添加注解即可**,以前调用是ribbon+restTemplate,现在直接用Openfegin就能实现接口的调用。
Feign旨在使编写Java Http客户端变得更容易。
前面在使用Ribbon+RestTemplate时,利用RestTemplate对http请求的封装处理,形成了一套模版化的调用方法。但是在实际开发中,由于对服务依赖的调用可能不止一处,往往一个接口会被多处调用,所以通常都会针对每个微服务自行封装一些客户端类来包装这些依赖服务的调用。所以,Feign在此基础上做了进一步封装,由他来帮助我们定义和实现依赖服务接口的定义。在Feign的实现下,我们只需创建一个接口并使用注解的方式来配置它(以前是Dao接口上面标注Mapper注解,现在是一个微服务接口上面标注一个Feign注解即可),即可完成对服务提供方的接口绑定,简化了使用Spring cloud Ribbon时,自动封装服务调用客户端的开发量。
Feign集成了Ribbon
利用Ribbon维护了Payment的服务列表信息,并且通过轮询实现了客户端的负载均衡。而与Ribbon不同的是,通过feign只需要定义服务绑定接口且以声明式的方法,优雅而简单的实现了服务调用.
**自带负载均衡**
#### 4.2OpenFegin使用步骤
1. 接口+注解
@EnableFeignClients
2. 新建cloud-consumer-fegin-order80
3. pom
```xml
org.springframework.cloud
spring-cloud-starter-openfeign
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
com.atguigu.springcloud
cloud-api-commons
${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
```
4. yml
```yml
server:
port: 80
eureka:
client:
register-with-eureka: false
service-url:
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
```
5. 主启动类
```java
@SpringBootApplication
//激活开启Feign
@EnableFeignClients
public class OrderFeginMain80
{
public static void main( String[] args )
{
SpringApplication.run(OrderFeginMain80.class,args);
}
}
```
6. 业务类
- 业务逻辑层接口+@FeignClient配置调用provider服务
- 新建PaymentFeignService接口并新增注解@FeignClient(value = "CLOUD-PAYMENT-SERVICE")
- 控制层Controller
#### 4.3超时控制(暂未完成)
#### 4.4日志打印功能(暂未完成)
### 5.Gateway新一代网关
#### 5.1概述简介(异步非阻塞)
SpringCloud Gateway 是 Spring Cloud 的一个全新项目,**基于 Spring 5.0+Spring Boot 2.0 和 Project Reactor 等技术开发的网关,它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式。**
SpringCloud Gateway 作为 Spring Cloud 生态系统中的网关,目标是替代 Zuul,在Spring Cloud 2.0以上版本中,没有对新版本的Zuul 2.0以上最新高性能版本进行集成,仍然还是使用的Zuul 1.x非Reactor模式的老版本。而为了提升网关的性能,SpringCloud Gateway是基于WebFlux框架实现的,而WebFlux框架底层则使用了高性能的Reactor模式通信框架Netty。
Spring Cloud Gateway的目标提供统一的路由方式且基于 Filter 链的方式提供了网关基本的功能,例如:安全,监控/指标,和限流。

GateWay的特性:
基于Spring Framework 5, Project Reactor 和 Spring Boot 2.0 进行构建;
动态路由:能够匹配任何请求属性;
可以对路由指定 Predicate(断言)和 Filter(过滤器);
集成Hystrix的断路器功能;
集成 Spring Cloud 服务发现功能;
易于编写的 Predicate(断言)和 Filter(过滤器);
请求限流功能;
支持路径重写。
#### 5.2三大核心概念
- Router(路由)
路由是构建网关的基本模块,**它由ID,目标URI,一系列的断言和过滤器组成**,如果断言为true则匹配该路由
- Predicate(断言)
开发人员可以匹配HTTP请求中的所有内容(例如请求头或请求参数),如果请求与断言相匹配则进行路由
- Filter(过滤)
指的是Spring框架中GatewayFilter的实例,使用过滤器,可以在请求被路由前或者之后对请求进行修改。
#### 5.3入门配置
网关作为一种微服务也要使用注册中心,在这里添加了eureka client,而且gateway是不需要web启动的依赖
pom.xml
```xml
org.springframework.boot
spring-boot-starter
org.springframework.cloud
spring-cloud-starter-gateway
3.1.2
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
3.1.2
org.springframework.boot
spring-boot-starter-test
test
```
网关配置有两种:
- 在yml文件中配置
```xml
server:
port: 9527
spring:
application:
name: cloud-gateway
cloud:
gateway:
#路由需要配置 id,uri,predicate,是使用list('-'加上一个空格)来进行添加的
routes:
#路由的id,没有固定的规则但要求唯一,建议配合服务名
- id: payment_route
#匹配后提供服务的路由地址
uri:
http://localhost:8001
#断言 路径相匹配的的进行路由
predicates:
- Path=/payment/get
#通过访问http://localhost:9527/payment/get 跳转到http://localhost:8001/payment/get
eureka:
instance:
hostname: cloud-gateway-service
client: #服务提供者provider注册进eureka服务列表中
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://eureka7001.com:7001/eureka
```
- 代码注入
代码注入比较麻烦 暂不推荐
#### 5.4通过微服务名实现动态路由
默认情况下Gateway会根据注册中心的服务列表以注册中心上**微服务名为路径创建动态路由进行转发,从而实现动态路由的功能。**
实现流程:
- 开启从注册中心动态创建路由的功能,利用微服务名进行路由
- 将uri修改为微服务名
```yaml
server:
port: 9527
spring:
application:
name: cloud-gateway
cloud:
gateway:
routes:
- id: payment_route
uri: lb://CLOUD-PAYMENT-SERVICE
# http://localhost:8001
predicates:
- Path=/payment/get
discovery:
locator:
#开启从注册中心动态创建路由的功能,利用微服务名进行路由
enabled: true
#路由需要配置 id,uri,predicate,是使用list('-'加上一个空格)来进行添加的
eureka:
instance:
hostname: cloud-gateway-service
client: #服务提供者provider注册进eureka服务列表中
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://eureka7001.com:7001/eureka
```

#### 5.5Predicate的使用(暂未完成)
#### 5.6Filter的使用(暂未完成)
# 由于电脑内存不够,关于后续微服务的学习将转到以下项目学习
https://gitee.com/yang1yu/study-mini-service2.git