什么是SpringCloudAlibaba?
Spring Cloud Alibaba真实应用场景
Spring Cloud Alibaba与Spring Cloud
- 总结来说:
- 组件性能更强
- 良好的可视化界面
- 搭建简单,学习曲线低
- 文档丰富并且是中文
阅读本博客你能学到什么?
课程进阶会讲那些内容?
课程思路:
SpringCloud Alibaba的重要组件精讲,如图所示:
课上用到的软件
安装Maven:
安装JDK和MySQL
- 根据自己实际配置好Group及Artifact,Type选Maven(若为Gradle项目也可以选Gradle),其他根据实际配置,如图所示:
- 选择需要的依赖,同时选择SpringBoot版本,其中如图所示的,除了2.1.5外,上方的都不是正式版,所以我们选择版本为2.1.5,如图所示:
我们可以自己部署一个Costom,结合官方文档和网上文章,当为内王环境时,自己就可以部署一个,如图所示:
![在这里插入图片描述](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/e82b5ebb18414b448932f48cfdcb729a~tplv-k3u1fbpfcp-zoom-1.image)
复制代码
通过启动启动类,直接就可以运行项目,我们不需要打war包再放到tomcat中了;
是什么? |
---|
加依赖: org.springframework.boot spring-boot-starter-actuator 复制代码
直接启动,访问:ip:端口/actuator
我们在application.yml中配置,让健康检查更加详细: management.endpoint.health.show-details=always 复制代码
如图所示:
- status取值:
- UP: 正常
- DOWN: 遇到了问题,不正常
- OUT\_OF\_SERVICE: 资源未在使用,或者不该去使用
- UNKNOWN: 不知道
- info:不是用于监控的,我们一般用于描述应用,使用key-value形式去写,如图所示:
- 展示内容如图:
支持的配置格式:
properties中的值若为 * ,在yml中则需要改为 “*” yml>yaml>properties 执行顺序,如果有重复内容,则properties为最终的结果
环境变量:
命令行中: java -jar xxx.jar --server.port=8081 复制代码
IDEA中:
- 在IDEA中指定要启动的环境:
- 不指定环境配置的时候,就只执行公共部分的配置,我们可以配置默认的环境配置方案,如图所示:
- 方式二:
- 我们也可以创建出多个profile配置文件,然后在配置的时候选择指定的配置文件,如图所示:
微服务定义
微服务的特性:
微服务架构图:
微服务的优点:
微服务的缺点:
微服务的适用场景
微服务不适用的场景
xxx此处省略
安装Node.js
假定已有对应nodejs前端项目
打包命令: npm install 复制代码
打包加速命令: npm --registry https://registry.npm.taobao.org install 复制代码
开发环境启动部署: npm run dev 复制代码
生产环境构建: npm run build 复制代码
下载&安装微信开发者工具:
去掉原来的依赖(如果存在) org.mybatis.spring.boot mybatis-spring-boot-starter 复制代码
换成通用mapper tk.mybatis mapper-spring-boot-starter 2.1.5 复制代码
在启动类上使用MapperScan注解扫描需要的接口 @MapperScan(“xxx”) 复制代码
如图所示:
1. application.yml中配置mysql相关信息
通用Mapper专用代码生成器生成的Model会在原有基础上增加@Table,@Id,@Column等注解,方便自动回数据库字段进行映射。运行MBG有多种方法,这里只是介绍两种比较常见的方法。并且有关的内容会针对这样的运行方式进行配置;
1. 使用Java编码方式运行MBG:
- 在Generatr项目测试代码中包含这个例子: https://github.com/abel533/Mapper/blob/master/generator/src/test/java/tk/mybatis/mapper/generator/Generator.java 复制代码
要使用这种方式,需要引入MBG的依赖,同时项目中应该已经有通用Mapper的依赖了。
1. 使用Plugin的方式去运行:
1. 将如图代码引入pom.xml中的对应位置:
maven-compiler-plgin在SpringBoot中提供了,我们可以不用加
1. 在 **resources/generator**目录下创建generatorConfig.xml文件,如图所示:
1. 可以去百度这个文件下的内容,将对应的占位符信息填充即可
1. 如果有外部的config.properties引用,我们需要单独创建一个,将里面引入的比如username,password等信息在config.properties中补充,如图所示:
1. 补充完,并且在generatorConifg.xml中配置好了所有的内容后,点击右侧Maven的插件: mybaits-generator 选择generate即可生成代码,如图所示:
1. 它能生成model,也能生成通用maper的代码,如图所示:
作用: 简化代码编写,提升开发效率
项目主页:([www.prjectlombok.org/)https://w…
IDEA中整合Lombok:
- 在IDEA中安装好了插件后,引入下方依赖(也可以自行百度最新版本)
org.projectlombok lombok 1.18.8 provided 复制代码
- 使用@Getter,@Setter,@ToString,@EqualsAndHashCode可以自动生成getter,setter,tostring等方法,如图所示:
- 注解说明:
- 使用@Data就相当于使用上面这几个注解,它内部聚合了这几个注解;
- @RequiredArgsConstructor是为标记为final的属性生成构造方法;
- @Builder使用了建造者模式,可以以这种方式去创建对象并且同时赋值;
- @Sl4j 注解,可以直接使用log功能
- 稳定功能和实验室功能,具体的可以在官网查看功能说明及示例;
- lombok与代码生成器:
- Lombok增加model代码生成时,可以直接生成lombok的@Getter@Setter@ToString@Accessors(chain=true)四类注解
- 使用者在插件配置项中增加 即可生成对应包含注解的model类
可以看到 userMapper
下有一个红色警告。虽然代码本身没有问题,能正常运行,但有个警告总归有点恶心。本文分析原因,并列出解决该警告的集中方案;
@Autowired
默认情况下要求依赖对象(也就是 userMapper
)必须存在。而IDEA认为注射个对象的实例/代理是个null,所以就友好的给个提示。- 方法二:用 `@Resource`替换 `@Autowired`
- 方法三: 在Mapper接口上加上@Repository注解
- 方法四: 使用Lombok的注解,使用构造方法注入的方式;
- 直接在类上面使用此注解即可: @RequiredArgsConstructor() 复制代码
- 也可以使用此方式,更推荐: @RequiredArgsConstructor(onConstructor = @\_\_(@Autowired)) 复制代码
- 如图所示:
- 总结: 此种方式最为推荐,原因有2:
1. Spring官方并不建议直接在类的field上使用@Autowired注解,原因详见 《Why field injection is evil》,用本方法可将field注入编程构造方法注入,Spring是比较推荐的。
2. 体现了Lombok的优势,简化了你的代码。而且你也不用在每个field上都加上@Autowired注解了。
不过这种方式也有缺点: 那就是如果你类之间的依赖比较复杂,特别是存在循环依赖(A引用B,B引用A,或者间接引用时),引用将会启动不起来…这其实是构造方法注入方式的缺点;
- 方式五: 把IDEA的警告关闭掉
- 方式六: 安装Mybatis plugin插件(如图所示:)
- 我们整理后如图所示:
- 整合SpringCloudAlibaba
- 如果使用的是Greenwich版本,则使用如图依赖:
- 如果使用的是Finchley版本,则使用如图依赖:
- 第一种方式整合cloud以及Alibaba如图所示:
使用了如图所示内容后,我们在引入Cloud中的其他组件时,可以不指定版本,它会自动配置对应的版本。如果没有使用如图内容可能会导致依赖冲突,依赖不一致的情况;
下载Nacos Server
搭建Nacos Server
启动服务器:
Linux/Unix/Mac: sh startup.sh -m standalone 复制代码
Windows: cmd startup.md 复制代码
此处启动命令为单机模式,非集群模式
加依赖: org.springframework.cloud spring-cloud-starter-alibaba-nacos-discovery 复制代码
在SpringCloud中的依赖规则与SpringBoot类似。官方项目是以此作为结构:spring-cloud-starter-{spring cloud子项目的名称}-{模块名称},比如feign可以这样:spring-cloud-starter-openfeign,而sentinel可以这样:spring-cloud-starter-alibaba-sentinel,当没有模块的时候,就不用加模块了,比如feign就没有
加注解:
加配置: spring: cloud: discovery: server-addr: localhost:8848 #指定nacos server的地址 application: name: 服务名称 # 比如 user-center,服务名称尽量用- ,不要用_ 复制代码
使用DiscoverClient的相关Api可以在代码中获取Nacos提供的微服务的一些信息,调用方法如图:
![在这里插入图片描述](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f701b2756963448cb9ea4663c70e0ec2~tplv-k3u1fbpfcp-zoom-1.image)
复制代码
- 然后在代码中添加字段:
手写负载均衡器主要原理就是获取到此服务的所有url,然后以轮询、随机等方式进行调用指定的url
- 使用RestTemplate:
在与启动类包下创建: @RibonClient(name = “服务名称”, configuration=RibbonConfiguration.class) public class XXXRibbonConfiguration{ } 复制代码
如图所示:
- 在与启动类包不同路径下创建: @Configuration public class RibbonConfiguration{ @Bean public IRule ribbonRule(){ // 随机 return new RandomRule(); } } 复制代码
- 如图所示:
Ribbon的启动类不能被启动类扫描到,不然容易发生父子上下文重叠,出现各种bug问题;
在resource目录下的application.yml中添加配置: xxx服务名称: ribbon: NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 想要的规则的类的所在全路径 复制代码
如图所示:
属性配置方式优先级更高。
代码配置和属性配置与之前上面的自定义配置一样;
application.yml
中进行配置: ribbon: eager-load enabled: true clients: xxx服务名 # 多个服务,以 ,
号分割 复制代码此处为开启饥饿加载
AbstractLoadBalancerRule
并实现方法,如图所示:- 补全代码:
- 定义Bean替换默认的:
- 在Nacos中编辑权重:
Feign是NetFlix的一款声明式远程调用HTTP客户端;
GitHub地址
整合办法:
pom.xml中引入依赖 org.springframework.cloud spring-cloud-starter-openfeign 复制代码
写注解,启动类上加上 @EnableFeignClients
注解
写配置,暂时没有
写一个Feign示例: @FeignClient(name=“xxx服务名称”) public interface xxxFeignCLient{ /** * 这是一个Feign的失恋了 * * / @GetMapping(“xxx/xxx”) XXX findById(xxx xxx) } 复制代码
类似于如图所示:
Feign与Ribbon也可以一起整合,可以参考Feign的整合方式
使用RequestInterceptor可以进行拦截,我们可以加上通用逻辑,比如为每个Feign的方法在调用的时候,都加上Header,Header里可以统一带上AuthToken
Feign的日志级别与通用的日志级别不同,它自己定义了四种日志级别
在配置类中,不能加@Configuration,如果加了必须在启动类能扫描的地方以外,否则会发生父子上下文异常,导致全局共享这个配置类
使用@SpringQueryMap 推荐,如图所示: @FeignClient(“xxxx-xx”) public interface UserFeignClient{ @GetMapping("/get") public User get0(@SpringQueryMap User user); } 复制代码
方法二:Url中有几个参数,Feign接口中的方法就有几个参数。使用@RequestParam注解指定请求的参数是什么 @FeignClient(“xxxx-xx”) public interface UserFeignClient{ @GetMapping("/get") public User get0(@RequestParam(“id”)Long id,@RequestParam(“username”)String str); } 复制代码
多参数的Url也可以使用Map来进行构建。当目标Url参数非常多的时候,可使用这种方式简化Feign接口的编写: @FeignClient(“xxxx-xx”) public interface UserFeignClient{ @GetMapping("/get") public User get0(@RequestParam Map
调用时可以使用类似如图代码:
在早期的Spring Cloud版本中,无需提供name属性,从Brixton版开始,@FeignClient必须提供name属性,否则应用将无法正常启动;
如何选择?
配置连接池(提升15%左右)
配置HttpClient:
引入依赖: io.github.openfeign feign-httpclient 复制代码
application.yml中进行配置: feign: client: config: #全局配置 default: loggerLevel: full httpclient: # 让Feign使用 apache httpclient做请求,而不是默认的urlHttp enabled: true # feign的最大连接数 max-connections:200 # feign单个路径的最大连接数 max-connections-per-route: 50 复制代码
如图所示:
也可以使用OkHttp:
引入依赖: io.github.openfeign feign-okhttp 10.1.0 复制代码
在application.yml中增加配置:
比如这个船,里面每个船舱都是独立的,当一个船舱进水了,也不会导致所有的船舱进水,从而使船沉没。每个Controller作为一个“船舱”
引入依赖:
org.springframework.cloud spring-cloud-starter-alibaba-sentinel 复制代码
引入actuator
org.springframework.boot spring-boot-starter-actuator 复制代码
application.yml 加入配置,暴露端点:
1. 访问 localhost:服务端口号/actuator/sentinel,出现如下图所示画面,即为配置完成:
1. 传入服务器,运行以下命令启动:
1. 访问web页面:ip/8080/#/login,输入账号密码均为: sentinel
1. 添加配置:
spring: cloud: sentinel: transport: # 指定sentinel 控制台地址 dashboard: localhost:8080 复制代码
sentinel是懒加载
QPS 和线程数,是过滤条件,以哪种方式来进行过滤。单机阀值是达到多少量后进行流控;
流控模式有三种,分别是直接、关联和链路。直接就是最常见的一种模式,限流达到了,直接对这个接口生效。而流控效果就是生效的三种形式;快速失败也是最常用的一种,就是当达到阀值后,这个直接接口直接返回失败。而流控模式-关联 表示,当访问填入入口资源的路径的单机阀值触发了,此接口就会触发所选择的流控效果;而链路就表示只对此入口过来的数据对此接口触发限流规则;Warm up是热等待,它会在指定的时间后完成触发效果;排队等待是不返回失败,而是进行排队,一个处理完了,再去处理另外一个。
Warm Up
- 它可以让流量缓慢增加。
RT降级规则图示:
- 图二:
RT 默认最大4900ms,通过 -Dcsp.sentinel.statistic.max.rt=xxx 修改
注意点: 时间窗口 < 60秒可能会出问题 比如我们设置时间窗口为10秒,当触发降级内如果异常数依然触发降级,那么可能会再次降级
源码:
官方解释:
1. 配置热点规则
源码地址:
- 定时推送到控制台
1. 用控制台配置规则时,控制台是如何将规则发送到各个微服务的呢?
这样就会统计这个流控,同时如果超过限流阀值,就会执行catch内的代码;
来源:
结尾需要关闭流
- 针对此来源的服务可以进行单独限流规则:
主要API:
后期我们可以用更简单的办法来实现,但都是基于此上图中的代码实现的;
这里面的block可以处理限流或者降级。处理降级可以单独使用fallback关键字,然后也类似于block一样写一个方法即可;升级到sentinel 1.6 可以处理Throwable
相关源码:
开关在 application.yml中进行配置
1. 代码中使用RestTemplate即可,这样会在Sentinel获取到监控信息,如果将开关改为false,则就不能获取到信息了。
1. 在Feign中指向一个类:
1. 补全这个类:
1. Feign去引用这个FallbackFactory:
配置好了重新刷新可能会没有数据展示,可以先去访问接口再回来刷新,因为它是懒加载模式;
网关gateway也可以实现类似集群流控的效果,且更加简单,性能更好;
1. 编写代码:
1. 返回结果
关注公众号:程序媛小琬 获得。
整理了一些Java面试资料大全 (Docker、Spring全家桶笔记和面试资料,1187页PDF+Java核心知识点+面试专题+20年最新的互联网真题+电子书等更多资料大礼包) 其中有:基础知识、JVM、Java集合、Netty、Kafka、Java算法、数据库、Zookeeper、分布式缓存、数据结构、Mybatis、Mysql、多线程并发编程等等。