Cloud总结
nacos
作为配置中心,服务注册中心,集成了ribbon,直接使用restTemplate进行服务调用
- 作为服务注册中心开发步骤
// 父pom
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.1.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
// 子模块
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
// yml配置
spring:
cloud:
nacos:
discovery:
server-addr: localhost:8848
management:
endpoints:
web:
exposure:
include: '*'
// 启动类添加注解@EnableDiscoveryClient
- 作为配置中心的使用步骤
<!-- 1. pom中引入依赖 -->
<!--nacos-config-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!--nacos-discovery-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
- yml配置
# bootstrap.yml
spring:
cloud:
nacos:
discovery:
server-addr: localhost:8848 #Nacos服务注册中心地址
config:
server-addr: localhost:8848 #Nacos作为配置中心地址
file-extension: yaml #指定yaml格式的配置
# application.yml
Spring:
profiles:
active: dev # 开发环境
- 启动类添加注解@EnableDiscoveryClient
- 最后只需启动nacos,浏览器打开nacos控制台,编写配置文件
- 参考案例
sentinel
限流,当前服务中降级处理,使用feign服务调用时降级处理,sentinel规则持久化到nacos
- 限流使用步骤
- 引入依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
- 配置sentinel
spring:
cloud:
sentinel:
transport:
dashboard: localhost:8080
port: 8719
-
启动sentinel,启动当前项目,访问一个路由地址,就能在sentinel控制台配置限流规则了
-
降级处理步骤
-
控制层中添加一个方法,@SentinelResource用于指定降级方法
@GetMapping("/testHotKey")
@SentinelResource(value = "testHotKey",blockHandler/*兜底方法*/ = "deal_testHotKey")
public String testHotKey(@RequestParam(value = "p1",required = false) String p1,
@RequestParam(value = "p2",required = false) String p2) {
return "------testHotKey";
}
/**
* 兜底的方法
* 降级处理时,sentinel系统默认的提示:Blocked by Sentinel (flow limiting)
* 这里可自定提示页面
*/
public String deal_testHotKey (String p1, String p2, BlockException exception) {
return "------deal_testHotKey,o(╥﹏╥)o";
}
-
之后在sentinel控制台配置限流规则即可
-
解决降级方法膨胀
// 1. 新建类用于管理所有兜底的方法
public class CustomerBlockHandler {
public static String handlerException(BlockException exception) {
return "按客戶自定义,global handlerException----1";
}
public static String handlerException2(BlockException exception) {
return "按客戶自定义,global handlerException----2";
}
}
// 2. 控制层中编写方法测试
@GetMapping("/testC")
@SentinelResource(value = "customerBlockHandler",
blockHandlerClass = CustomerBlockHandler.class,
blockHandler = "handlerException2")
public String testC()
{
log.info(Thread.currentThread().getName()+"\t"+"...testC");
return "------testC";
}
-
之后在sentinel控制台配置限流规则即可
seata
用于解决分布式事务问题
-
安装配置
-
下载seata-server
-
修改file.conf,目的是使seata连接mysql
-
创建seata数据库,自己要操作的业务数据库需添加undo.log表
-
seata安装路径下创建logs文件夹,创建seata_gc.log文件,避免启动报错
-
修改registry.conf,目的是使nacos作为seata的服务中心和配置中心
-
将seata配置导入nacos配置中心:
-
进入seata/script/config-center/config.txt,修改为自己的mysql数据库
-
双击seata/script/config-center/nacos/nacos-config.sh,执行导入操作,之后启动nacos,浏览器访问nacos控制台/配置管理/配置列表
-
启动seata,浏览器访问nacos控制台/服务管理/服务列表
-
项目配置
-
cloud项目整合Seata:在分布式微服务项目中添加如下即可
-
父工程依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
- 子模块依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>
- yml配置,每个服务都需配置
seata:
enabled: true
application-id: ${spring.application.name}
enable-auto-data-source-proxy: true
tx-service-group: my_test_tx_group # 与下面相同
registry:
type: nacos # nacos作为seata服务注册中心
nacos:
application: seata-server
server-addr: http://localhost:8848
username: nacos
password: nacos
group: SEATA_GROUP
config:
type: nacos # nacos作为seata配置中心
nacos:
application: seata-server
server-addr: http://localhost:8848
username: nacos
password: nacos
group: SEATA_GROUP
service:
vgroup-mapping:
my_test_tx_group: default # 与上面相同
disable-global-transaction: false
client:
rm:
report-success-enable: false
-
添加注解@GlobalTransactional
-
项目中未添加file.conf和registry.conf,因为config.txt导入nacos后,sentinel的配置都已经写入nacos配置中心,启动项目后会自动去nacos配置中心获取sentinel的配置
-
报错一:no available server to connect
# 解决方案
# yml配置中添加属性spring.cloud.alibaba.seata.tx-service-group,值需与file.conf中的分组一致
spring:
cloud:
alibaba:
seata:
#自定义事务组名称需要与seata-server中的对应
tx-service-group: my_test_tx_group
gateWay
需新建一个module作为网关:用于反向代理,隐藏微服务的IP;用于负载均衡,访问网关,由网关进行请求转发;用于过滤,只有指定规则的请求才能进来
- 1.隐藏真实的ip
<!--引入依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- 不需要引入的依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
- 核心代码,注意格式
spring:
cloud:
# 网关配置
gateway:
routes:
- id: payment_routh # 自定义路由id,必须唯一
uri: http://localhost:8001 # 真实地址
predicates:
- Path=/payment/ok/** # 断言,路径与8001控制层的路由相匹配
- id: payment_routh2
uri: http://localhost:8001
predicates:
- Path=/payment/timeout/**
- 2.网关实现负载均衡,前提是网关模块和要转发的服务集群已经注册到服务注册中心
- 设置动态路由的核心代码
spring:
application:
name: cloud-gateway
cloud:
nacos:
discovery:
server-addr: localhost:8848 # 1. 注册到nacos
gateway:
discovery:
locator:
enabled: true # 2. 开启从注册中心动态创建路由的功能,利用微服务名进行路由
routes:
- id: payment_routh
# uri: http://localhost:8001 # 3. 注释真实地址
uri: lb://gateway-provider # 4. 配置服务集群
predicates:
- Path=/payment/ok/**
- id: payment_routh2
# uri: http://localhost:8001
uri: lb://gateway-provider
predicates:
- Path=/payment/timeout/**
- 3.gateway作为过滤器
- 在yml配置中设置断言,不满足断言规则的路由请求将被拦截
- 参考案例
restTemplate
- nacos中集成了ribbon,也就是说将服务注册到nacos,就能直接使用restTemplate,并且自带负载功能
// 配置类
@Configuration
public class ApplicationContextConfig {
@Bean
@LoadBalanced
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
}
// 控制层使用restTemplate进行服务调用
@RestController
public class OrderController {
// 1. 被调用者的ip+端口
public static final String PAYMENT_URL = "http://localhost:8001";
// 2. 注入restTemplate
@Resource
private RestTemplate restTemplate;
// 访问http://localhost:80/consumer/payment/create,即可访问到被调用者的接口
@GetMapping("/consumer/payment/create")
public CommonResult<Payment> create(Payment payment){
return restTemplate.postForObject(PAYMENT_URL+"/payment/create", payment, CommonResult.class);
}
}
ribbon
- 用于服务调用和服务调用时的负载
- 在nacos中已经集成了ribbon,通常只需要在nacos中使用即可
- 在其他的服务注册中心使用ribbon,自定义负载规则的步骤如下:
- 引入依赖
<dependency>
<groupld>org.springframework.cloud</groupld>
<artifactld>spring-cloud-starter-netflix-ribbon</artifactid>
</dependency>
- 自定义负载规则配置类
// nginx实现负载均衡属于集中式LB,即在服务的消费方和提供方提供LB设施,当消费方发请求调提供方时,消费方的请求会先进入nginx,通过nginx转发分配到提供方集群
// Ribbon属于进程内LB,消费方自己选择调用哪个提供方
// 当消费者模块调用提供者模块集群时,在消费者模块自定义规则类;自定义的规则类不能放在@ComponentScan所扫描的当前包及其子包下
@Configuration
public class MySelfRule {
@Bean
public IRule myRule(){
return new RandomRule();
}
}
// 在消费者模块的启动类添加注解,指定要负载的集群和自定义的负载规则;前提是这个集群和当前消费者模块已经注册到服务注册中心
@RibbonClient(name = "CLOUD-PAYMENT-SERVICE", configuration = MySelfRule.class)
openFeign
- 用于服务调用,在消费者模块的业务层编写接口即可,前提是服务消费者和服务提供者集群已注册到nacos
- Feign和OpenFeign两者区别:Feign是在服务注册中心调用其他服务,openFeign是能动态调用,如负载均衡
- Feign集成了Ribbon
// 1.在消费者模块引入openFeign依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
// 启动类添加注解
@EnableFeignClients
// 新建feign接口
// FeignClient注解中指定的服务名称必须与服务提供者一致,严格区分大小写
// 同时要调用的方法中返回值、参数等也必须一致
@Component
@FeignClient(value = "cloud-provider-service")
public interface PaymentFeignService {
@GetMapping(value = "/payment/getPayment/{id}")
public String getPaymentById(@PathVariable("id") Integer id);
}