SpringCloud Alibaba 入门简介
诞生: 2018.10.31,Spring Cloud Alibaba 正式入驻了 Spring Cloud 官方孵化器,并在 Maven 中央库发布了第一个版本。
能干嘛?
服务限流降级:默认支持 Servlet、Feign、RestTemplate、Dubbo 和 RocketMQ 限流降级功能的接入,可以在运行时通过控制台实时修改限流降级规则,还支持查看限流降级 Metrics 监控。 服务注册与发现:适配 Spring Cloud 服务注册与发现标准,默认集成了 Ribbon 的支持。 分布式配置管理:支持分布式系统中的外部化配置,配置更改时自动刷新。 消息驱动能力:基于 Spring Cloud Stream 为微服务应用构建消息驱动能力。 阿里云对象存储:阿里云提供的海量、安全、低成本、高可靠的云存储服务。支持在任何应用、任何时间、任何地点存储和访问任意类型的数据。 分布式任务调度:提供秒级、精准、高可靠、高可用的定时(基于 Cron 表达式)任务调度服务。同时提供分布式的任务执行模型,如网格任务。网格任务支持海量子任务均匀分配到所有 Worker(schedulerx-client)上执行。
SpringCloud Alibaba Nacos服务注册和配置中心
nacos的简介:
各注册中心比较:
Nacos作为服务注册中心演示
基于Nacos的服务提供者
-
导入依赖
-
yml
server:
port: 9001
spring:
application:
name: nacos-payment-provider
cloud:
nacos:
discovery:
server-addr: localhost:8001 #配置Nacos地址
management:
endpoints:
web:
exposure:
include: '*'
- controller
@RestController
public class PaymentController
{
@Value("${server.port}")
private String serverPort;
@GetMapping(value = "/payment/nacos/{id}")
public String getPayment(@PathVariable("id") Integer id)
{
return "nacos registry, serverPort: "+ serverPort+"\t id"+id;
}
}
- 测试
服务nacos-payment-provider 注册到了nacos
基于Nacos的服务消费者 调用提供者9001和9002,实现负载均衡
-
导入依赖
-
yml
server:
port: 83
spring:
application:
name: nacos-order-consumer
cloud:
nacos:
discovery:
server-addr: localhost:8001
#消费者将要去访问的微服务名称(注册成功进nacos的微服务提供者)
service-url:
nacos-user-service: http://nacos-payment-provider
- nacos中集成了ribon,编写ApplicationContextConfig类,引入RestTemplate
@Configuration
public class ApplicationContextConfig
{
@Bean
@LoadBalanced
public RestTemplate getRestTemplate()
{
return new RestTemplate();
}
}
- controller
@RestController
@Slf4j
public class OrderNacosController
{
@Resource
private RestTemplate restTemplate;
@Value("${service-url.nacos-user-service}")
private String serverURL;
@GetMapping(value = "/consumer/payment/nacos/{id}")
public String paymentInfo(@PathVariable("id") Long id)
{
return restTemplate.getForObject(serverURL+"/payment/nacos/"+id,String.class);
}
}
服务注册中心对比
- C是所有节点在同一时间看到的数据是一致的;而A的定义是所有的请求都会收到响应。
- 何时选择使用何种模式?
- 一般来说,如果不需要存储服务级别的信息且服务实例是通过nacos-client注册,并能够保持心跳上报,那么就可以选择AP模式。当前主流的服务如 Spring cloud 和 Dubbo 服务,都适用于AP模式,AP模式为了服务的可能性而减弱了一致性,因此AP模式下只支持注册临时实例。
- 如果需要在服务级别编辑或者存储配置信息,那么 CP 是必须,K8S服务和DNS服务则适用于CP模式。CP模式下则支持注册持久化实例,此时则是以 Raft 协议为集群运行模式,该模式下注册实例之前必须先注册服务,如果服务不存在,则会返回错误。
curl -X PUT '$NACOS_SERVER:8848/nacos/v1/ns/operator/switches?entry=serverMode&value=CP'
Nacos作为服务配置中心演示
- yml
# nacos配置
server:
port: 3377
spring:
application:
name: nacos-config-client
cloud:
nacos:
discovery:
server-addr: localhost:8001 #Nacos服务注册中心地址
config:
server-addr: localhost:8001 #Nacos作为配置中心地址
file-extension: yaml #指定yaml格式的配置
# group: DEV_GROUP
# namespace: 7d8f0f5a-6a53-4785-9686-dd460158e5d4
# ${spring.application.name}-${spring.profile.active}.${spring.cloud.nacos.config.file-extension}
# nacos-config-client-dev.yaml
# nacos-config-client-test.yaml ----> config.info
spring:
profiles:
active: dev # 表示开发环境
#active: test # 表示测试环境
#active: info
注意nacos上配置中心文件的名字
- controller,注解@RefreshScope支持动态刷新
@RestController
@RefreshScope //支持Nacos的动态刷新功能。
public class ConfigClientController
{
@Value("${config.info}")
private String configInfo;
@GetMapping("/config/info")
public String getConfigInfo() {
return configInfo;
}
}
- 测试
Nacos作为配置中心-分类配置
1 是什么
类似Java里面的package名和类名 最外层的namespace是可以用于区分部署环境的,Group和DataID逻辑上区分两个目标对象。
2 三者情况
默认情况:
- Namespace=public,Group=DEFAULT_GROUP, 默认Cluster是DEFAULT
- Nacos默认的命名空间是public,Namespace主要用来实现隔离。比方说我们现在有三个环境:开发、测试、生产环境,我们就可以创建三个Namespace,不同的Namespace之间是隔离的。
- Group默认是DEFAULT_GROUP,Group可以把不同的微服务划分到同一个分组里面去
- Service就是微服务;一个Service可以包含多个Cluster(集群),Nacos默认Cluster是DEFAULT,Cluster是对指定微服务的一个虚拟划分。比方说为了容灾,将Service微服务分别部署在了杭州机房和广州机房,这时就可以给杭州机房的Service微服务起一个集群名称(HZ),给广州机房的Service微服务起一个集群名称(GZ),还可以尽量让同一个机房的微服务互相调用,以提升性能。
- 最后是Instance,就是微服务的实例。
Nacos集群和持久化配置(重要)
- application.properties
spring.datasource.platform=mysql
db.num=1
db.url=jdbc:mysql://127.0.0.1:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
db.user=root
db.password=123
Linux版Nacos+MySQL生产环境配置
- Linux服务器上nacos的集群配置cluster.conf hostname -i
192.168.152.130
- Nginx的配置,由它作为负载均衡器
upstream cluster{
server 127.0.0.1:3333;
server 127.0.0.1:4444;
server 127.0.0.1:5555;
}
server {
listen 1111;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
#root html;
#index index.html index.htm;
proxy_pass http://cluster;
}.......省略
upstream是nginx的负载均衡ip映射配置
- 启动linux中3台nacos 进去bin目录
cd /mynacos/bin
./startup.sh -p 3333
./startup.sh -p 4444
./startup.sh -p 5555
- 查看nacos启动端口 ps -ef |grep nacos|grep -v grep |wc -l
出现的问题: 1.不成功的有失败信息。因为nacos运行需要的内存不小,一般可能是因为内存不足,内存不足信息:
修改内存大小
修改后
内存给的太小会打不开nacos
2.nginx: [emerg] unknown directive " " in /usr/local/nginx/conf/nginx.conf:39
手敲配置文件,因为格式会有问题
- 启动nginx 1.进入nginx的sbin目录
cd /usr/local/nginx/sbin
2.输入nginx启动命令
./nginx -c /usr/local/nginx/conf/nginx.conf
3.查看是否启动nginx
ps -ef |grep nginx
http://192.168.152.130:1111/nacos/#/login
nacos集群启动问题:
- 1.启动模式由单机改为集群
- 2.JVM分配内存改动以下,不能改太小
- 3.复制3个nacos,改动端口分别启动
- 4.改变配置文件
- 5.启动脚本
cd /mynacos/bin
./startup.sh
/mynacos3999/bin
./startup.sh
- 测试
访问linux中nacos端口
通过nginx端口1111成功访问到集群nacos端口
- 在配置中心新增一条配置
- 在linux中查询mysql数据库,可以查到此数据
- 把9002nacos-payment-provider注册进去linux的nacos中 yml
server:
port: 9002
spring:
application:
name: nacos-payment-provider
cloud:
nacos:
discovery:
# server-addr: localhost:8001 #配置Nacos地址
# 换成nginx的1111端口,做集群
server-addr: 192.168.152.130:1111
management:
endpoints:
web:
exposure:
include: '*'
总结:
SpringCloud Sleuth 分布式请求链路跟踪
Sleuth启动
java -jar -文件名
- cloudalibaba-sentinel-service8401实例
yml
server:
port: 8401
spring:
application:
name: cloudalibaba-sentinel-service
cloud:
nacos:
discovery:
server-addr: localhost:8001 #Nacos服务注册中心地址
sentinel:
transport:
dashboard: localhost:8080 #配置Sentinel dashboard地址
port: 8719
# datasource:
# ds1:
# nacos:
# server-addr: localhost:8848
# dataId: cloudalibaba-sentinel-service
# groupId: DEFAULT_GROUP
# data-type: json
# rule-type: flow
#management:
# endpoints:
# web:
# exposure:
# include: '*'
#
#feign:
# sentinel:
# enabled: true # 激活Sentinel对Feign的支持
流控规则
基本介绍:
进一步说明:
QPS和线程数的区别:
QPS是某一秒最大访问量
线程数是要等某个线程执行完后其他线程才能执行
关联:
使用postman并发访问testB:
降级规则
基本介绍:
例子:
例子:
例子:
热点key限流
controller层:blockHandler是兜底方法,SentinelResource注解中的value是资源名,方便找到热点参数。
@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)
{
//int age = 10/0;
return "------testHotKey";
}
public String deal_testHotKey (String p1, String p2, BlockException exception)
{
return "------deal_testHotKey,o(╥﹏╥)o"; //sentinel系统默认的提示:Blocked by Sentinel (flow limiting)
}
参数例外项:
相当于如果用户是VIP则不限制
@SentinelResource 注解
用户自定义限流处理逻辑:
84调用9003和9004,Sentinel的使用
为什么不用全局异常处理,用fallback,因为服务之间的调用。 用fallback表示程序发生异常的兜底处理。 blockHandler 是sentinel控制台配置违规,比如设定了降级规则,违反了就触发。
@RequestMapping("/consumer/fallback/{id}")
//@SentinelResource(value = "fallback") //没有配置
//@SentinelResource(value = "fallback",fallback = "handlerFallback") //fallback只负责业务异常
//@SentinelResource(value = "fallback",blockHandler = "blockHandler") //blockHandler只负责sentinel控制台配置违规
@SentinelResource(value = "fallback",fallback = "handlerFallback",blockHandler = "blockHandler",
exceptionsToIgnore = {IllegalArgumentException.class})
public CommonResult<Payment> fallback(@PathVariable Long id)
{
CommonResult<Payment> result = restTemplate.getForObject(SERVICE_URL + "/paymentSQL/"+id,CommonResult.class,id);
if (id == 4) {
throw new IllegalArgumentException ("IllegalArgumentException,非法参数异常....");
}else if (result.getData() == null) {
throw new NullPointerException ("NullPointerException,该ID没有对应记录,空指针异常");
}
return result;
}
sentinel服务熔断Feign
- yml
# 激活Sentinel对Feign的支持
feign:
sentinel:
enabled: true
- 主启动类
@EnableDiscoveryClient
@SpringBootApplication
@EnableFeignClients
public class OrderNacosMain84
{
public static void main(String[] args) {
SpringApplication.run(OrderNacosMain84.class, args);
}
}
- service层
@FeignClient(value = "nacos-payment-provider",fallback = PaymentFallbackService.class)
public interface PaymentService
{
@GetMapping(value = "/paymentSQL/{id}")
public CommonResult<Payment> paymentSQL(@PathVariable("id") Long id);
}
- 兜底类
@Component
public class PaymentFallbackService implements PaymentService
{
@Override
public CommonResult<Payment> paymentSQL(Long id)
{
return new CommonResult<>(44444,"服务降级返回,---PaymentFallbackService",new Payment(id,"errorSerial"));
}
}
测试84调用9003,此时故意关闭9003微服务提供者,看84消费侧自动降级,不会被耗死
规则持久化
- 一旦我们重启应用,sentinel规则将消失,生产环境需要将配置规则进行持久化
- 将限流配置规则持久化进Nacos保存,只要刷新8401某个rest地址,sentinel控制台的流控规则就能看到,只要Nacos里面的配置不删除,针对8401上sentinel上的流控规则持续有效
nacos配置:
[
{
"resource": "/rateLimit/byUrl",
"limitApp": "default",
"grade": 1,
"count": 1,
"strategy": 0,
"controlBehavior": 0,
"clusterMode": false
}
]
resource:资源名称;
limitApp:来源应用;
grade:阈值类型,0表示线程数,1表示QPS;
count:单机阈值;
strategy:流控模式,0表示直接,1表示关联,2表示链路;
controlBehavior:流控效果,0表示快速失败,1表示Warm Up,2表示排队等待;clusterMode:是否集群。