【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>
spring boot 开发
官方的插件与非官方插件格式
spring boot actuator 监控
spring boot 配置管理
使用 yml 配置 还是使用 properties 配置
推荐yml :
1. 可读性
2. 如果在 yml 的话,对于springboot 来说 读取配置内容是有序读取的,
但是 properties 就不一定是 按照配置顺序读取配置项的
比如 上面的 yml的话就是 先读取 users 配置然后到 legacy 配置
配置设置 优先级
以上 SOME_ENV就是启动的时候 指定环境变量 。同时 使用 命令行参数也是 一样的使用方式
yml 指定不同环境的 使用 属性
微服务适用场景
1.大型,复杂项目
2. 有快速迭代的需求
3. 访问压力大
不适用微服务场景
1. 业务稳定
2. 迭代周期长
微服务拆分
方法论
DDD 在国内不流行,不过正在越来越流行,可以去了解
心得
合理的粒度
1. 良好地满足业务
2. 幸福感: 团队不会觉得微服务很大,部署方便,每次部署不需要部署很多微服务
3. 增量迭代 : 每次迭代都是 迭代有限个微服务,发布也是发布有限个微服务
4. 持续进化: 对微服务进行再拆分与合并
spring cloud alibaba 简介
参考 文档 https://github.com/alibaba/spring-cloud-alibaba/blob/master/README-zh.md
https://www.jianshu.com/p/63c521f098be
版本与兼容性
什么是 nacos
文档: https://nacos.io/zh-cn/docs/what-is-nacos.html
nacao 的服务发现的领域模型
即高版本的group 功能可能会生效。在 0.9 版本没有生效
nacos 元数据
nacos 可以通过 namespace 做好 服务集群的隔离。
即不同 namespace的 微服务不能 互相调用
Ribbon
组成
负载均衡规则
@Configuration 注解使用 注意 spring 容器父子 上下文
那是因为 ribbon 的 容器 也会扫描这个 这个类。
而主 容器 spring boot 也会扫描这个类,
这就是 所谓的 父子上下文 扫描重叠
就可能 出现 各种各样奇怪的问题。比如 事务不生效
因此 这个 ribbon 配置类要放在 spring boot 启动类扫描不到的地方。
否则 这样的配置就会变成 全局规则,而不是 针对某个微服务的规则
配置属性
代码配置与属性配置
最佳实践
全局配置
支持的配置项
ribbon 饥饿加载
默认 ribbon 是 懒加载的
因此就会 出现 首次请求 过慢,而可能出现超时的问题
改成 饥饿加载
扩展ribbon 支持 nacos 权重
因为 nacos 可以为 微服务配置权重的,而 ribbon 没有
因此需要自己是实现这种 算法 ,而 nacos 已经 实现了,改写一下即可
package com.itmuch.contentcenter.configuration;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.alibaba.nacos.NacosDiscoveryProperties;
import org.springframework.cloud.alibaba.nacos.ribbon.NacosServer;
@Slf4j
public class NacosWeightedRule extends AbstractLoadBalancerRule {
@Autowired
private NacosDiscoveryProperties nacosDiscoveryProperties;
@Override
public void initWithNiwsConfig(IClientConfig clientConfig) {
// 读取配置文件,并初始化NacosWeightedRule
}
@Override
public Server choose(Object key) {
try {
BaseLoadBalancer loadBalancer = (BaseLoadBalancer) this.getLoadBalancer();
// log.info("lb = {}", loadBalancer);
// 想要请求的微服务的名称
String name = loadBalancer.getName();
// 拿到服务发现的相关API
NamingService namingService = nacosDiscoveryProperties.namingServiceInstance();
// nacos client自动通过基于权重的负载均衡算法,给我们选择一个实例。
Instance instance = namingService.selectOneHealthyInstance(name);
log.info("选择的实例是:port = {}, instance = {}", instance.getPort(), instance);
return new NacosServer(instance);
} catch (NacosException e) {
return null;
}
}
}
// spring cloud commons --> 定义了标准
// spring cloud loadbalancer --> 没有权重
扩展方式 参考 https://www.imooc.com/article/288660
扩展Ribbon -基于元数据的版本控制
参考 https://www.imooc.com/article/288674
Feign
自定义Feign日志级别
在配置文件配置:
全局配置日志
支持的配置项
最佳实践
Feign的继承
即 controller 实现一个 接口,而 feign 继承 这个 接口。 这样来使用。
好处就是比较有 契约精神 ,代码重用
官方不建议这样使用,这样就是 紧耦合了
但是 业界 很多公司这样使用。
因此要 拳皇利弊, 再使用。
多参数请求构造
即当 多个 feign 类 注解服务名称的相同的时候,就需要加上下面的配置
spring
main:
allow-bean-definition-overriding: true
多参数的时候 需要 加上 @SpringQueryMap
多参数 的参考 https://www.imooc.com/article/289000
feign 脱离Ribbon 使用
RestTemplate VS Feign
feign性能优化
1. 使用连接池
使用 okhttp 或者 apache httpclient 都可以 。只是需要加上对应的mavne依赖
设置合适的feign日志级别
生产不建议设置日志级别为 full , 可以设置为 basic
Feing 常见问题
参考 https://www.imooc.com/article/289005
spring cloud gateway
为什么需要网关?
1. 统一授权认证
2. 通信协议 可能不同,进行处理
3. 统一维护
优点。缺点
规则
核心概念
架构
路由谓词工厂
参考 https://www.imooc.com/article/290804
自定义路由谓词工厂
自定义的路由谓词工厂要以
RoutePredicateFactory 结尾
内置过滤器工厂
参考 https://www.imooc.com/article/290816
自定义过滤器工厂
方式1
方式2
核心API
过滤器工厂命名一定要以 GatewayFilterFactory 结尾
全局过滤器
参考 https://www.imooc.com/article/290821
监控 spring cloud gateway
参考 https://www.imooc.com/article/290822
排查,调试技巧
参考 https://www.imooc.com/article/290824
过滤器执行顺序
网关限流
参考 https://www.imooc.com/article/290828
或者 整合 sentinel 或者 hytrix
监控网关
参考 https://www.imooc.com/article/290822
服务容错 sentinel
雪崩效应: 也叫 cascading failure 级联失效,级联故障。
即比如当 高并发的时候,如果 某个服务挂了,那么调用该服务的服务那么就存在大量的线程等待阻塞,因为线程 直到连接失败或者连接超时 才会 销毁, 而造成的雪崩效应,因此才需要服务容错。
常见容错方案
超时 。意义: 只有线程释放够快就不会出现问题,
限流 。思想: 一次只能承受这么多,
仓壁模式(比如某个服务的 调用接口分配一定的线程池,那么该服务挂了,不会造成雪崩效应). 比喻: 不把鸡蛋放在一个篮子里
断路器模式 。 思想: 监控加开关
sentinel
文档: https://github.com/alibaba/Sentinel/wiki/%E4%BB%8B%E7%BB%8D
依赖与监控端点:
sentinel 控制台
控制台访问路径 localhost:8080 , 账号 sentinel ,密码也是 sentinel
流控规则
关联这里 用法: 比如 当 关联的资源比如 修改的API ,当修改的API达到某个阈值,就限制查询API 自己
链路: 用法:比如 针对某个接口或者某个来源进行细粒度的限流
流控效果
1. 快速失败:
2. Warm Up 预热
即让 允许通过的流量或者请求 缓慢增加,而不是一下子都 过来,避免 高峰请求
类似: 削峰填谷
3. 排队等待
适用于 应对 特发情况: 比如 某时候很多请求,某时候 很少请求。
而且不是 请求很多的时候 就丢弃请求,就可以使用这样的,这样可以在服务 空闲的时候
处理 之前的请求
降级规则
1. RT : 平均响应时间
2. 降级 - 异常比例
源码:
官网文档可能不太对,一切以代码和 实际测试为准
热点规则
即可以 对 请求参数 进行 限流,比如某些请求参数的QPS非常高,更细致化,提高了 api 接口的可用性
否则其他参数 不生效
源码:
系统规则
系统load负载
可以使用 uptime 查看系统负载
源码:
授权规则
配置 服务的 白名单与黑名单
代码配置规则
参考 http://www.imooc.com/article/289345
sentinel 与 控制台 通信原理
sentinel 定时获取信息,且它们 有心跳,即实现了一套 服务发现机制
源码
控制台配置项
控制台 配置项1
比如 知道用户名和密码
sentinel API
在代码里面定义 sentinel 保护的资源。之后就可以在 sentinel 控制台对其进行 设置 规则了
@SentinelResource详解
参考 http://www.imooc.com/article/289384
源码
RestTemplate整合Sentinel
使用注解即可。 默认是 sentinel.enabled=true .
当开发调试的时候,可以使用 设置 sentinel 为false
Feign整合sentinel
使用总结
规则持久化
拉模式与推模式
参考 http://www.imooc.com/article/289402
参考 http://www.imooc.com/article/289464
生产环境使用sentinel
如果不想改造 规则持久化 ,则可以使用阿里云的 AHAS ,就比较方便了
推模式还是拉模式根据 实际情况权衡使用
集群流控
目前 Token Server 还有点问题,不支持 生产使用。新版本以后再说
扩展sentinel 错误页优化
urlBlockHandler 接口 可以对 错误 进行处理
扩展 区分来源
比如 针对来源 与 流控应用
实现接口即可
扩展-支持RESTful URL
因为 sentinel 的控制台配置流控 规则的路径不支持 restful 因此需要自己扩展
扩展 -看本质
本质就是 通过 过滤器进行处理的,这里是 CommonFilter
如果 想自定义 可以 通过参考或者改写 CommonFilter 里面的实现
配置项总结
参考 https://www.imooc.com/article/289562
sentinel 的仓壁模式,并没有 使用 线程池进行隔离实现。
如果 使用类似hytix 那种,一个接口配置一个小型线程池,
如果线程池数量很多,那么线程数就会过多,肯定会对性能造成影响。
而 sentinel 还是使用 一个线程池,只是 比如某个接口 指定使用某些线程。
这样线程数就会过多。
sentinel 流程图
用户认证与授权
OAuth2 实现单点登录
https://www.cnblogs.com/cjsblog/p/10548022.html
处处安全方案
外部无状态,内部有状态 方案
网关认证授权,内部裸奔方案
优点: 实现简单,性能好
缺点: 网关的登录认证被破就有风险
内部裸奔 改进方案
可以减低方案的复杂度,提升安全性。但是秘钥被泄露的风险增加了
方案对比与选择
访问控制模型
jwt
工具类 参考 https://www.imooc.com/article/290892
Feign 实现token
或者 使用 feign 的拦截器来 传递 token 值
Nacos 配置管理
1.不同环境不同配置
2. 配置属性动态刷新
引入依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>${spring-cloud-alibaba.version}</version>
</dependency>
配置映射
这样nacos 才可以找到配置文件。当然了 这里 profiles 可以没有。
那么 dataID 就只能是 应用名.yaml 了 那么该配置就是 通用的配置
编写一个 bootstrap.yml 文件 该文件就是对应的 配置管理
即 nacos 把 服务发现和配置管理分开了。可以获得更好的性能,职责更单一
bootstrap.yml 就是 配置管理
而 applicaion.yml 类似的配置文件里面配置的就是 服务发现 等 内容
配置属性动态刷新与回滚
在对应的配置类加上 加上 @RefreshScope 注解即可
可以不适用历史版本的回滚功能, 直接修改配置 发布即可
应用的配置共享
在 bootstrap.yml 文件配置上面的
引导上下文
本地配置和远程配置优先级
默认远程配置优先级更高
以上配置 需要配置在 nacos 里面 才生效的, 否则放在项目的 boostrap.yml 等其他地方是不生效的。
nacos 数据持久化
默认nacos的数据是存放在本地的
配置的信息数据 默认是存在在 derby 的内嵌数据库里面的
快照目录(存放配置数据,做容灾用):
当然 可以配置 nacos 的持久化可以改为 存放在 mysql 里面
搭建生产可用nacos 集群
参考 https://www.imooc.com/article/288153
最佳实践
sleuth 调用链监控
整合sleuth
zipkin
搭建参考 https://www.imooc.com/article/291572
zipkin maven包已经包含了 sleuth
抽样率,即 丢弃 数据,只取部分数据给zipkin
nacos 报错解决
https://www.imooc.com/article/291578
zipkin 数据 持久化
zipkin 环境变量
其他环境变量
可以通过环境变量 设置 持久化的目标比如 es
如果使用es 存储那么需要一个 spark job 才可以分析到依赖关系图
其他环境变量:
多维度监控微服务
一般工具:
spring boot admin
可以将 spring boot actuator 监控数据可视化
JVM监控
GC日志、线程Dump日志、堆dump可视化
日志监控
elk
RocketMQ
搭建RocketMQ
参考 http://www.imooc.com/article/290089
控制台 改造安装 : http://www.imooc.com/article/290092
rocketMQ的术语与概念
MQ 生产者
MQ 消费者 使用注解
参考 spring boot 文档:
分布式事务-MQ
rocket mq 的事务处理
即二次确认 事务提交
消息三态
seata流程图
整合异构微服务
即比如 整个项目a 是java 开发的, 而服务b是go 语言开发的,将不同语言的给整合起来
即 springcloud 微服务 与 异构微服务 要满足以下三点:
例子可以参考
spring cloud stream 通用操作MQ
以上是 stream 的架构图, middleware 代表消息中间件
编程模型
比如:
上图 应用 消费 rabbitMQ消息,处理之后,将消息 发送给kafka
消息过滤
参考 http://www.imooc.com/article/290424
stream 监控
/actuator 监控里面有
stream 异常处理
参考 http://www.imooc.com/article/290435
stream 知识盘点
参考 http://www.imooc.com/article/290489
代码质量工具SonarQube
安装参考 https://www.imooc.com/article/291857
或者使用 idea 的 Statistic 插件去 总体粗略查看项目代码质量。
比如 查看 代码的 注释量
来源:oschina
链接:https://my.oschina.net/ouminzy/blog/3154012