文章目录
第三部分Nacos配置中心
1.配置Nacos的配置中心流程
(1)先新建一个controller类【并加注解@Slf4j,因为这个注解可以新建一个log对象】
@Slf4j
@RestController
public class ProviderLogController {
//创建一个日志对象
//org.slf4j.Logger (Java中的日志API规范,基于这个规范有Log4J,Logback等日志库)
//org.slf4j.LoggerFactory
//log对象在哪个类中创建,getLogger方法中的就传入哪个类的字节码对象
//记住:以后只要Java中使用日志对象,你就采用下面之中方式创建即可.
//假如在log对象所在的类上使用了@Slf4j注解,log不再需要我们手动创建,lombok会帮我们创建
@GetMapping("/provider/log/doLog01")
public String doLog01(){//trace<debug<info<warn<error
System.out.println("==doLog01==");
log.trace("===trace===");
log.debug("===debug===");
log.info("===info====");
log.warn("===warn===");
log.error("===error===");
return "log config test";
}
}
(2)然后添加依赖
【依赖如下:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
】
(3)然后修改YML文件并修改名字【项目中的配置文件名为bootstrap.yml】
【修改文件如下:
server:
port: 8082
spring:
application:
name: sca-provider
cloud:
nacos:
discovery: #配置注册中心
server-addr: localhost:8848
config: #配置配置中心
server-addr: localhost:8848
file-extension: yml】
(4)然后去nacos中新增一个配置,并添加配置内容
【内容如下:
logging:
level:
com.jt: debug
】
(5)最后输入网址进行测试即可
2.yml中改变日志的级别
logging:
level:
com.jt: debug【根据业务来设置】
3.基于@RefreshScope注解的应用的配置
第一步:在ProviderLogController类的上面添加一个@RefreshScope注解
@RefreshScope
@RestController
public class ProviderLogController{
//.....
}
第二步:添加ProviderLogController中添加一个获取日志级别
(debug<info<warn<error)的的属性和方法,
@Value("${logging.level.com.jt:error}")
private String logLevel;
@GetMapping("/provider/log/doLog02")
public String doLog02(){
log.info("log level is {}",logLevel);
return "log level is "+logLevel;
}
第三步:启动sca-provider服务,然后打开浏览器并输入http://localhost:8081/provider/log/doLog02进行访问测试。
4.共享配置设计及读取的配置
(1)先在nacos中创建一个共享配置文件,并生成一个秘钥【配置中心设置】
【写法:app:
secret: AAAAA】
(2)配置YML文件
【写法:
spring:
cloud:
nacos:
config:
shared-configs[0]:
data-id: app-public.yml
refresh: true #默认false,共享配置更新,引用此配置的地方是否要更新】
(3)在指定的Controller类中读取和应用共享配置即可
【写法:
@RefreshScope
@RestController
public class ProviderSecretController {
@Value("${app.secret:123456}")
private String secret;
@GetMapping("/provider/secret")
public String doGetSecret(){
return "The Secret is "+secret;
}
}
】
(4)启动服务,然后打开浏览器进行访问测试。
5.模仿本地缓存配置
(1)先在创建一个controller类并在类上加注解【@RestController和@Refreshscope】
(2)然后并创建缓存对象,并通过@Value获取配置文件中的值
(3)然后通过CopyOnWriteArrayList创建一个list集合对象
(4)然后定义一个方法
(5)通过Arrays.asList方法模拟封装成一个数据库
(6)然后判断一下缓存对象是否为false
(7)然后判断一下list集合是否为空看看一下是否满足条件
(8)如果满足条件就通过同步锁进入,不满足就直接返回list集合对象
(9)进入同步锁然后在继续进行判断list集合是否为空,为空时,把数据库的数据就加入list集合中,不满足返回list集合对象
【代码如下:
@RefreshScope
@RestController
public class ProviderCacheController {
@Value("${userLocalCache:false}")
private boolean userLocalCache;
private List<String> cache=new CopyOnWriteArrayList<>();
@RequestMapping("/doCache")
public List<String> doCache() {
List<String> cacheList = Arrays.asList("前端", "运维", "后端", "编程");
if (!userLocalCache) {
System.out.println("Data from Database");
return Arrays.asList("前端", "运维", "后端", "编程");
}
if (cache.isEmpty()) {
synchronized (cache) {
if (cache.isEmpty()) {
System.out.println("从数据库获取");
cache.addAll(cacheList);
}
}
}
return cache;
}
}
】
6.分组设计及实现配置
(1)在配置中心配置不同组和userLocalCache的数据【配置中心】
userLocalCache=true
(2)配置YML文件,添加命名空间和组
【写法:
server:
port: 8081
spring:
application:
name: sca-provider
cloud:
nacos:
config:
server-addr: 127.0.0.1:8848
group: DEFAULT_GROUP_51
file-extension: yml
namespace: 7da4aa75-f64c-43c6-b101-9d77ad96f1c0【设置类命名空间ID】
】
(3)创建一个布尔类型的对象,通过@Value接收对象
package com.jt.provider.controller;
@RefreshScope
@RestController
public class ProviderCacheController {
@Value("${useLocalCache:false}")
private boolean useLocalCache;
@RequestMapping("/provider/cache01")
public String doUseLocalCache01(){
return "useLocalCache'value is "+useLocalCache;
}
}
(4)最后进行访问
第四部分sentinel熔断限流应用
1.启动Sentinel的步骤
(1)先在官网上下载Sentinel的jar包,并存储到本地文件夹
(2)找到存放Sentinel文件夹,并打开cmd,执行命令行启动
【命令如下:java -Dserver.port=8180 -Dcsp.sentinel.dashboard.server=localhost:8180 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.1.jar
】
(3)输入网址访问Sentinel服务【默认密码和账号:Sentinel】
2. 测试直接链路的配置
(1)先定义一个controller,并定义一个方法
(2)然后配置yml文件
【代码如下:
spring:
cloud:
sentinel:
transport:
dashboard: localhost:8180
】
(3)导入依赖
【依赖如下:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
】
(4)然后进入Sentinel进行配置【因为默认是直接限流,所以就设置阈值即可】
(5)最后通过定义好的网址访问
3. 测试关联链路的配置:【目的就是对重要的不要限流,对不重要的限流,让重要的先完成】
(1)在上个controller类中,再定义一个方法
(2)然后进入Sentinel进行配置
(3)然后点开高级选项,选择关联,在关联资源中设置成本方法的资源名,设置阈值
(4)最后通过定义好的网址访问
4. 测试链路模式的配置:
(1)先创建一个服务类和方法,别忘了@Server和@SentinelResource的注解
【代码如下:
package com.jt.provider.service;
@Service
public class ResourceService{
@SentinelResource("doGetResource")
public String doGetResource(){
return "doGetResource";
}
}
】
(2)然后再在第一个controller类中,添加一个方法
【代码如下:
@Autowired
private ResourceServer resourceServer;
@GetMapping("/provider/getSentinel2")
public String getSentinel2(){
return resourceServer.doResourceServer();
}
】
(3)在sentinel中配置限流规则,选择操作流控,在入口资源中写最上面标三角形的
(4)最后通过定义好的网址访问
【重要YML文件:链路不想执行sentinel聚集设置:
Sentinel:
web-context-unify: false 】
4. Sentinel链路异常处理配置:
(1)先创建一个业务层的方法并加上注解@Server和@SentinelResource(value = “ResourceServer”,
blockHandler = “handleBlock”,
blockHandlerClass = ResourceBlockHandler.class)
(2)然后创建一个ResourceBlockHandler的类,并加上注解@Slf4j和@Component交给Spring容器
还有一个方法
(3)创建一个ProviderSentinelController类,并注入业务层的对象
(4)最后访问一下
【限流的异常规则:
* @SentinelResource描述方法时,可以在控制台创建一个资源链路
* 这个链路的名称默认为value属性的值,当出现限流时,客户端默认看到的是
* 一个500异常,假如对限流结果进行处理,可以考虑使用handleBlockClass
* 属性指定一个限流处理类,然后通过指定handleBlock属性异常处理方法
* 这个异常处理方法必须与@SentinelResource描述的方法,返回值类型相同,
* 同时必须是static方法,方法中的参数可以是BlockException类型 】
5.Sentinel降级应用配置:
(1)通过创建AtomicLong类对象实现线程安全的自增自减操作
(2)定义一个方法
(3)方法内通过atomicLong.getAndIncrement方法获取自增对象的值
(4)通过判断2取余来模拟50%的慢调用比例
(5)设置休眠
(6)最终进行访问
6.Sentinel降级异常处理配置:【自定义限流,降级等异常处理对象】
(1)重新建一个类并实现 BlockExceptionHandler接口
(2)然后重写里面的handle方法
(3)设置响应数据编码,通过setCharacterEncoding方法
(4)告诉浏览器你要响应的内容类型和编码,通过setContentType方法
(5)构建响应数据【创建Map集合存储】
(6)将map转换为json格式字符串,通过writeValueAsString方法
(7)响应数据写到客户端,通过getWriter()方法
(8)最后访问即可
【代码如下:
@Slf4j
@Component
public class ServiceBlockExceptionHandler
implements BlockExceptionHandler {
/**
* 用于处理BlockException类型以及子类类型异常
*/
@Override
public void handle(HttpServletRequest request,
HttpServletResponse response,
BlockException e) throws Exception {
//设置响应数据编码
response.setCharacterEncoding("utf-8");
//告诉客户端响应数据的类型,以及客户端显示内容的编码
response.setContentType("text/html;charset=utf-8");
//向客户端响应一个json格式的字符串
//String str="{\"status\":429,\"message\":\"访问太频繁了\"}";
Map<String,Object> map=new HashMap<>();
map.put("status", 429);
map.put("message","访问太频繁了");
String jsonStr=new ObjectMapper().writeValueAsString(map);
PrintWriter out = response.getWriter();
out.print(jsonStr);
out.flush();
out.close();
}
}
】
注意点【重点】
- 日志级别:trace<debug<info<warn<error
- Nacos健康检查的方式?(基于心跳包机制进行实现)
- 注册中心是用于记录服务信息的一个web服务
- 为什么使用feign?(基于Feign可以更加友好的实现服务调用,简化服务消费方对服务提供方方法的调用)。
- 配置中心一般都会配置什么内容?(可能会经常变化的配置信息)
- Nacos配置管理模型:
- 配置中一般要配置什么内容?(经常变化的配置数据-日志级别,线程池、连接池、…)
- 配置中心选型时要重点考虑哪些因素?(市场活跃度、稳定性、性能、易用)
- 两个命名空间的共享配置不可互相调用
- Sentinel:分布式系统的流量防卫兵,用于服务容错【开源】,是流量控制平台
- Sentinel的算法:令牌桶、漏斗、计算器、滑动窗口算法(默认的)
- 阈值的类型有QPS(每秒查询)、线程数
- Sentinel的限流效果有快速失败,预热,排队
- 限流的模式:
(1)直接限流:对当前资源限流
(2)关联限流:高优先级资源触发阈值,对优先级资源限流
(3)链路限流:阈值统计时,只统计从指定资源进入当前资源的请求,是对请求来源的限流 【想象成红绿灯】
【@SentinelResource------在链路中描述节点】 - Sentinel中限流,降级的异常父类是BlockException
- Sentinel中异常处理接口是BlockExceptionHandler
- Sentinel 出现降级熔断时,系统底层抛出的异常是DegradeException
- Sentinel熔断降级策略有慢调用比例、异常比例、异常数
- 我们如何自己定义Sentinel中异常处理?答:直接或间接实现BlockExceptionHandler
- 降级熔断是让外部应用停止对服务的访问
- Sentinel是如何对请求进行限流的? 答:基于sentinel依赖提供的拦截器
- 降级规则配置代表的意义:
熔断策略选择"慢调用比例",表示请求数超过3时,假如平均响应时间超过200毫秒的有30%,
则对请求进行熔断,熔断时长为10秒钟,10秒以后恢复正常。