SpringBoot实用开发

SpringBoot实用开发

热部署

手动启动热部署

  1. 开启开发者工具后启动热部署
<dependency>
	<groupId>org.springframework.bootgroupId>
	<artifactId>spring-boot-devtoolsartifactId>
    <optional>trueoptional>
dependency>
  1. 使用构建项目操作启动热部署(Ctrl+F9)

  2. 热部署仅仅加载当前开发者自定义开发的资源,不加载jar资源

热部署

· 重启(Restart):自定义开发代码,包含类、页面、配置文件等,加载位置restart加载器

· 重载(ReLoad):jar包,加载位置base类加载器

自动启动热部署

· 设置自动构建项目

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QMLX5vWd-1647010003080)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220309172213579.png)]

· ctrl+shirt+ALT+/

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mAsfV2BB-1647010003082)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220309172246553.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lGaLkZjo-1647010003082)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220309172257629.png)]

· 激活方式:Idea失去焦点5秒后启动热部署

热部署范围配置

自定义不参与重启排除项

devtools:
 restart:
  exclude: public/**,static/**

默认不处罚重启的目录列表

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PF6ML3gG-1647010003083)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220309172913717.png)]

关闭热部署

· 设置高优先级属性禁用热部署

public static void main(String[] args){
    System.setProperty("Spring.devtools.restart.enabled",false);
    SpringApplication.run(SSMPApplication.class)
}

配置高级

@ConfigurationProperties

· 使用@ConfigurationProperties为第三方bean绑定属性

@Bean
@ConfigurationProperties(prefix="datasource")
public DruidDataSource dataSource(){
    DruidDataSource ds = new DruidDataSource();
    return ds;
}
datasource:
 driverClassName:com.mysql.jdbc.Driver

· @EnableConfigurationProperties注解可以将使用@ConfigurationProperties注解对应的类加入Spring容器

@SpringBootApplication
@EnableConfigurationProperties(ServerConfig.class)
public class DemoApplication{
    
}
//@Component
//@EnableConfigurationProperties与@Component不能同时使用
@Data
@ConfigurationProperties(prefix="servers")
public class ServerConfig{

}

· 解除使用@ConfigurationProperties注释警告

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AQ6kMC3x-1647010003084)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220309192724057.png)]

宽松绑定/松散绑定

  1. @ConfigurationProperties绑定属性支持属性名宽松绑定
@Bean
@ConfigurationProperties(prefix="datasource")
public DruidDataSource dataSource(){
    DruidDataSource ds = new DruidDataSource();
    return ds;
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ub96UgS0-1647010003084)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220309194016639.png)]

  1. @Value注解不支持松散绑定

  2. 绑定前缀命名规则

    1. 规范:仅能使用纯小写字母、数字、下划线作为合法字符

常用计量单位绑定

· SpringBoot支持JDK8提供的时间与空间计量单位

//@Component
@Data
@ConfigurationProperties(prefix="servers")
public class ServerConfig{
	private long timeout;
    @DurationUnit(ChronoUnit.MINUTES)
    private Duration serverTimeout;
    @DataSizeUnit(DataUnit.MEGABYTES)
    private DataSize dataSize;
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ouDXRLvj-1647010003085)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220309194650283.png)]

数据校验

  1. 添加JSR303规范坐标与Hibernate校验框架对应坐标
<dependency>
	<groupId>javax.validationgroupId>
    <artifactId>validation-apiartifactId>
dependency>

<dependency>
	<groupId>org.hibernate.validatorgroupId>
    <artifactId>hibernate-validatorartifactId>
dependency>
  1. 对Bean开启校验功能
@Component
@Data
@ConfigurationProperties(prefix="servers")
@Validated
public class ServerConfig{
    
}
  1. 设置校验规则
@Component
@Data
@ConfigurationProperties(prefix="servers")
@Validated
public class ServerConfig{
    @Max(value = 400,message="最大值不能超过400")
    private int port;
}

进制数据转换规则

  1. 注意yaml中对于数字的定义支持进制书写格式,如需使用字符串请使用引号明确标注

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZdnO9UTQ-1647010003086)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220309201112611.png)]

测试

加载测试专用属性

· 在启动测试环境时可以通过properties参数设置测试环境专用的属性

@SpringBootTest(properties={"test.prop=testValuel"})
public class PropertiesAndArgsTest{
    @Value("${test.prop}")
    private String msg;
    @Test
    void testProperties(){
        System.out.print(msg);
    }
}
//仅对当前测试类有效,多环境开发中的测试环境影响范围小

· 在启动测试环境时可以通过args参数设置测试环境专用的传入参数

@SpringBootTest(args={"--test.arg=testValue2"})
public class PropertiesAndArgsTest{
    @Value("${test.arg}")
    private String msg;
    @Test
    void testArgs(){
        System.out.print(msg);
    }
}

加载测试专用配置

· 使用@Import注解加载当前测试类专用的配置

@SpringBootTest
@Import(MsgConfig.class)
public class ConfigurationTest{
    @Autowired
    private String msg;
    @Test
    void testConfiguration(){
        System.out.println(msg);
    }
}

Web环境模拟测试

  1. 设置测试环境
  2. 模拟测试启动
  3. 模拟测试匹配(各组件部分信息均可匹配)

· 模拟端口

@SpringBootTest(webEnvironment = SpringBoot.WebEnvironment.RANDOM_PORT)
public class WebTest{
    @Test
    void testRandonPort(){
        
    }
}

· 虚拟请求测试

@SpringBootTest(webEnvironment = SpringBoot.WebEnvironment.RANDOM_PORT)
//开启虚拟MVC调用
@AutoConfigureMockMvc
public class WebTest{
    @Test
    //注入虚拟MVC调用对象
    public void WebTest(@Autowired MockMvc mvc) throws Exception{
        //创建虚拟请求,当前访问/books
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
        //执行请求
        ResultActions action = mvc.perform(builder);
    }
}

· 虚拟请求状态匹配

@Test
    public void WebSataus(@Autowired MockMvc mvc) throws Exception{
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
        ResultActions action = mvc.perform(builder);
        //配置执行状态(是否预期值)
        //定义执行状态匹配器
        StatusResultMatchers status = MockMvcRequestBuilders.status();
        //定义预期执行状态
        ResultMatcher ok=status.isOk();
        //使用本次真实执行结果与预期结果进行对比
        action.andExpect(ok);
    }

· 匹配响应体

@Test
    public void WebSataus(@Autowired MockMvc mvc) throws Exception{
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
        ResultActions action = mvc.perform(builder);
        //配置执行状态(是否预期值)
        //定义执行状态匹配器
        StatusResultMatchers content = MockMvcRequestBuilders.content();
        //定义预期执行状态
        ResultMatcher result = content().string("springboot");
        //使用本次真实执行结果与预期结果进行对比
        action.andExpect(result);
    }

· 匹配响应体(json)

@Test
    public void WebJson(@Autowired MockMvc mvc) throws Exception{
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
        ResultActions action = mvc.perform(builder);
        //配置执行状态(是否预期值)
        //定义执行状态匹配器
        StatusResultMatchers content = MockMvcRequestBuilders.content();
        //定义预期执行状态
        ResultMatcher result = content.json("{\"id\":1}");
        //使用本次真实执行结果与预期结果进行对比
        action.andExpect(result);
    }

· 匹配响应头

@Test
    public void WebContentType(@Autowired MockMvc mvc) throws Exception{
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
        ResultActions action = mvc.perform(builder);
        //配置执行状态(是否预期值)
        //定义执行状态匹配器
        HeaderResultMatchers header = MockMvcResultMatchers.header();
        //定义预期执行状态
        ResultMatcher resultHeader = header.string("Content-Type","application/json");
        //使用本次真实执行结果与预期结果进行对比
        action.andExpect(resultHeader);
    }

数据层测试回滚

· 为测试用例添加事务,SpringBoot会对测试用例对应的事务提交操作进行回滚

@SpringBootTest
@Transactional
public class DaoTest{
    @Autowired
    private BookService bookService;
}

· 如果想在测试用例中提交事务,可以通过@Rollback注解设置

@SpringBootTest
@Transactional
@Roolback(false)
public class DaoTest{
    @Autowired
    private BookService bookService;
}

测试用例数据设定

· 使用随机数据替换测试用例中书写固定的数据

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3yBYUhPh-1647010003086)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220309220717621.png)]

数据层解决方案

SQL

· 现有数据层解决方案技术选型

Druid+Mybatis-Plus+MySQL

数据源:DruidDataSource

  1. SpringBoot内置3种数据源
    1. HikariCP:默认内置数据源对象
    2. Tomcat提供DataSource: HikariCP不可用的情况下,且在web环境中,将使用tomcat服务器配置的数据源对象
    3. Commons DBCP: HikariCP不可用,tomcat数据源也不可用,将使用dbcp数据源

持久化技术:MyBatis-Plus/MyBatis

  1. 内置持久化解决方案-JdbcTempllate
<dependency>
	<groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-jdbcartifactId>
dependency>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HC4GgsXm-1647010003087)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220310110052274.png)]

数据库:MySQL

· SpringBoot提供了三种内嵌数据库

  1. H2
  2. HSQL
  3. Derby
H2
  1. 设置当前项目为web工程,并配置H2管理控制台参数
server:
 port:80
spring:
 h2:
  console:
   path: /h2
   enabled: true
  1. 设置访问数据库
server:
 port:80
spring:
 datasource:
  driver-class-name: org.h2.Driver
  url: jdbc:h2:~/test
  username: sa
  password: 12346
 h2:
  console:
   path: /h2
   enabled: true
  1. H2数据库控制台仅用于开发阶段,线上项目务必关闭控制台功能
server:
 port:80
spring:
 h2:
  console:
   path: /h2
   enabled: false

NoSQL

Redis

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O2VmAZkp-1647010003087)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220310115518112.png)]

· 导入SpringBoot整合Redis坐标

<dependency>
	<groupId>org.spring.bootgroupId>
    <artifactId>spring-boot-starter-redisartifactId>
dependency>

· 配置Redis(采用默认配置)

spring:
 redis:
  host: localhost # 1270.0.01
  prot: 6379

· RedisTemplate提供操作各种数据存储类型的接口API

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OqFUFqbV-1647010003088)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220310120925434.png)]

RedisTemplate

· 以对象作为key和value,内部对数据进行序列化

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FfloW69J-1647010003088)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220310121110040.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q0MBwbIO-1647010003089)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220310121121155.png)]

StringRedisTemplate

· 以字符串作为key和value,与Redis客户端操作等效

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nzaRAEp8-1647010003089)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220310121811264.png)]

Springboot整合Redis客户端选择

· lettuce(默认)

· jedis

· lettcus和jedis的区别

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D2agy8Sn-1647010003090)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220310122422010.png)]

Mongo

· 开源、高性能、无模式的文档型数据库

·Mongo的应用场景

Mongo安装、启动

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-U8FKUqD7-1647010003090)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220310144008348.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p6hOj0mb-1647010003091)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220310144020355.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8Ir8Cw7W-1647010003091)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220310144600352.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Xw6GlRH7-1647010003092)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220310144632295.png)]

基础操作CRUD

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UNugHUPe-1647010003093)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220310145349181.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TGHHQZSv-1647010003093)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220310145407089.png)]

整合Mongodb
  1. 导入Mongodb对应的starter
  2. 配置mongodb访问uri
  3. 提供操作Mongodb接口对象MongoTemplate

· 导入Mongodb驱动

<dependency>
	<groupId>org.springframework-mongodbgroupId>
    <artifactId>spring-boot-starter-mongodbartifactId>
dependency>

· 配置客户端

spring:
 data:
  mongodb:
   uri:mongodb://localhost/mhp

· 客户端读写Mongodb

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZboJZZCk-1647010003094)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220310150518245.png)]

ES

· Elasticesearch是一个分布式英文搜索引擎

索引–>倒排索引–>创建文档–>使用文档

下载

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2kt53le4-1647010003094)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220310152239187.png)]

1. 创建/查询/删除索引

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iyytLzRj-1647010003095)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220310153444351.png)]

2. Ik分词器

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3W5tIvnI-1647010003095)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220310153530995.png)]

3. 创建索引并指定规则

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mhMutRe9-1647010003095)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220310153605438.png)]

ES文档操作

· 创建文档

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3cnDlOv3-1647010003096)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220310154521918.png)]

· 查询操作

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VRr9Zg21-1647010003096)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220310154601664.png)]

· 删除文档

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wkjfHWo7-1647010003096)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220310154618310.png)]

· 修改文档

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-10a3Cqw3-1647010003097)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220310154720904.png)]

SpringBoot整合ES

· low level Client整合方案

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UbELcCSl-1647010003097)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220310155830081.png)]

· high level Client

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FY4PzUht-1647010003097)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220310155918343.png)]

· 创建客户端

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NtfvKb1y-1647010003098)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220310155937629.png)]

· 改进客户端

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PI2NM7Ri-1647010003098)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220310160014519.png)]

· 改进客户端

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nORewLca-1647010003098)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220310160110721.png)]

添加文档

· 创建索引

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vL9h7OFW-1647010003099)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220310161051615.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rxhsgw8O-1647010003099)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220310161101594.png)]

· 添加文档

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D9zVVcAA-1647010003099)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220310161117092.png)]

· 批量添加文档

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-goFAc77u-1647010003100)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220310161136544.png)]

查询文档

· 按id查询文档

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6mckgmiZ-1647010003100)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220310162203152.png)]

· 按条件查询文档

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hrI2w6tT-1647010003100)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220310162303802.png)]

整合第三方技术

缓存(cache)

缓存的作用

  1. 缓存时一种介于数据永久存储介质与数据应用之间的数据链式存储介质
  2. 使用缓存可以有效的减少低速数据读取过程的次数(例如磁盘IO),提高系统性能
  3. 缓存不仅可以用于提高永久性存储介质的数据读取效率,还可以提供临时的数据存储空间

Spring缓存使用方法

  1. @EnableCaching
  2. @Cacheable

· 导入缓存技术对应的starter

<dependency>
	<groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-cacheartifactId>
dependency>

· 启用缓存

@SpringBootApplication
@EnableCaching //启动缓存
public class CacheApplication{
    
}

· 设置当前操作的结果数据进入缓存

@Cacheable(value="cacheSpace",key="#id")
public Book getById(Integer id){
    return bookDao.selectById(id);
}

多种缓存方案

· 对其他缓存技术进行整合,统一接口,方便缓存技术的开发与管理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HpspF74S-1647010003101)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220310184640759.png)]

Ehcache

  1. 加入Ehcache坐标(缓存供应商实现)
<dependency>
	<groupId>net.sr.ehcachegroupId>
    <artifactId>ehcacheartifactId>
dependency>
  1. 缓存设定为使用Ehcache
spring:
 cache:
  type: ehcache
  ehcache: 
   config:ehcache.xml
  1. 提供ehcache配置文件chcache.xml

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd" updateCheck="false">
   

    <defaultCache
            maxElementsInMemory="10000"
            maxElementsOnDisk="10000000"
            eternal="false"
            overflowToDisk="true"
            timeToIdleSeconds="60"
            timeToLiveSeconds="60"
            diskExpiryThreadIntervalSeconds="60"
            memoryStoreEvictionPolicy="LRU">
    defaultCache>
ehcache>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sqvIjmQF-1647010003101)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220310201639922.png)]

数据淘汰策略

· 影响数据淘汰的相关配置

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JDI1Xi3A-1647010003101)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220310202128163.png)]

Redis

· 加入Redis坐标(缓存供应商实现)

<dependency>
	<groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-data-redisartifactId>
dependency>

· 配置Redis服务器,缓存设定为使用Redis

spring:
 redis:
  host: localhost
  proy: 6379
 cache:
  type:redis

· 设置Redis相关配置

memcached

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4dtkUeif-1647010003102)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220310203537273.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZPS6ufPS-1647010003102)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220310204059939.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tmba4lk3-1647010003102)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220310204111198.png)]

  1. xmemcached客户端加载方式(bean初始化)
  2. xmemcached客户端使用方式(set & get)

· 加入Xmemcache坐标

<dependency>
	<groupId>com.googlecode.xmemcachedgroupId>
    <artifactId>xmencachedartifactId>
dependency>

· 配置mencached服务器必要配置

memcached:
# memcached服务器地址
 server: localhost: 11211
 # 连接器的数量
 poolSize: 10
 #设置默认操作超时
 opTimeout:3000

· 创建读取属性配置信息类,加载配置

@Component
@ConfigurationProperties
@Data
public class XMemcachedProperties{
    private String servers;
    private Integer poolSize;
    private Long opTimeout;    
}

· 创建客户端配置类

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PflF51gh-1647010003102)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220310205742401.png)]

jetcache

· jetCache对SpringCache进行了封装,在原有功能基础上实现了多级缓存、缓存统计、自动刷新、异步调用、数据报表

· jetCache设定了本地缓存与远程缓存的多级缓存解决方案

· 本地缓存(local)

​ · LinkedHashMap

​ · Caffeine

· 远程缓存(remote)

​ · Redis

​ · Tair

  1. 加入jetcache坐标
<dependency>
	<groupId>com.alicp.jetcachegroupId>
    <artifactId>jetcache-starter-redisartifactId>
    <version>2.6.2version>
dependency>
  1. 配置远程缓存必要属性
jetcache:
 remote:
  default:
   type: redis
   host: localhost
   port: 6379
   poolConfig:
    maxTotal: 50   
  1. 配置本地缓存必要属性
jetcache:
 local:
  default:
   type: linkedhashmap
   keyConvertor: fastjson

配置属性说明:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HpHUyGGC-1647010003103)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220310213457916.png)]

  1. 开启jetcache注解支持
@EnableCreateCacheAnnotation
  1. 声明缓存对象
@CreateCache(name="smsCache",expire= 3600)
private Cache jetSMSCache;
方法缓存
  1. 启动方法注解
@SpringBootApplication
@EnableCreateCacheAnnotation
@EnableMethodCache(basePackages="com.xxx")
public class SpringbootJetCacheApplication{
    public static void main(Stringp[] args){
        SpringApplication.run(SpringbootJetCacheApplication.class,args)
    }
}
  1. 使用方法注解操作缓存
public class BookServiceUmpl implements BookService{
    @Autowired
    private BookDao bookDao;
    
    @Cached(name="smsCache_",key="#id",expire=3600)
    @CacheRefresh(refresh=10,timeunit=TimeUnit.SECONDS)
    public Book getById(Integer id){
        return bookDao.selectById(id)
    }
}
  1. 使用方法注解操作缓存
@CacheUpdate(name="smsCacha",key="#book.id",value="#book")
public boolean update(Book book){
    return bookDao.updateById(book)>0;
    
@CacheInvalidate()
}
  1. 缓存对象必须保障可序列化
@Data
public class Book implements Serializable{}
jetcache:
 remote:
  default:
   type redis
   keyConvertor: fastjson
   valueEncoder: java
   valueDecoder: java

j2cache

· j2cache是一个缓存整合框架,可以提供缓存的整合方案,使各种缓存搭配使用,自身不提供缓存功能

· 基于ehcache+redis 进行整合

  1. 加入j2cache坐标,加入整合缓存的坐标
<dependency>
	<groupId>net.oschina.j2cachegroupId>
    <artifactId>j2cache-spring-boots2-starterartifactId>
    <version>2.8.0version>
dependency>
<dependency>
	<groupId>net.oschina.j2cachegroupId>
    <artifactId>j2cache-coreartifactId>
    <version>2.8.4version>
dependency>
<dependency>
	<groupId>net.sf.ehcachegroupId>
    <artifactId>ehcacheartifactId> 
dependency>
  1. 配置使用j2cache(application.yml)
j2cache:
 config-location: j2cache.properties
  1. 配置一级缓存与二级缓存以及一级缓存数据到二级缓存的发送方式(j2cache.properties)
# 配置1级缓存
j2cache.L1.provider_class=ehcache
ehcache.configXml= ehcache.xml

# 配置1级缓存数据到2级缓存的广播方式:可以使用redis提供的消息订阅模式,也可以使用jgroups多播实现
j2cache.broadcast=net.oschina.j2cache.cache.support.redis.SpringRedisPubSubPolicy

# 配置2级缓存
j2cache.L2.provider_class=net.oschina.j2cache.cache.support.redis.SpringRedisProvider
j2cache.L2.config_section = redis
redis.hosts=localhost:6379
  1. 设置使用缓存
Autowired
    private CacheChannel cacheChannel;

任务

Quartz

相关概念:

· 工作(Job):用于定义具体执行的工作

· 工作明细(JobDetail):用于描述定时工作相关的信息

· 触发器(Trigger):用于描述触发工作的规则,通常使用cron表达式定义调度规则

· 调度器(Scheduler):描述了工作明细与触发器的对应关系

  1. 导入SpringBoot整合quartz的坐标
<dependency>
	<groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-quartzartifactId> 
dependency>
  1. 定义具体要执行的任务,继承QuartzJobBean
public class QuartzTaskBean extends QuartzJobBean{
    
}
  1. 定义工作明细与触发器,并绑定对应关系

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sC4OUUe2-1647010003103)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220311170208615.png)]

Spring Task
  1. 开启定时任务功能
@SpringBootApplication
@EnableScheduling //开启定时任务
  1. 设置定时执行的任务,并设定执行周期
@Scheduled(cron="")
public void printLog(){
    //执行任务
}
  1. 定时任务相关配置

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-F2pmV14F-1647010003104)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220311171031391.png)]

邮件

JavaMail

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-k8kfRzfl-1647010003104)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220311171732329.png)]

  1. 导入SpringBoot整合JavaMail的坐标
<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-mailartifactId>
dependency>
  1. 配置JavaMail
spring:
  mail:
    host: smtp.126.com
    username: [email protected]
    password: test
 #java程序仅用于发送邮件,邮件的功能还是邮件供应商提供的,所以这里是用别人的邮件服务,要配置对应信息。

# host配置的是提供邮件服务的主机协议,当前程序仅用于发送邮件,因此配置的是smtp的协议。

# password并不是邮箱账号的登录密码,是邮件供应商提供的一个加密后的密码,也是为了保障系统安全性。不然外部人员通过地址访问下载了配置文件,直接获取到了邮件密码就会有极大的安全隐患。有关该密码的获取每个邮件供应商提供的方式都不一样,此处略过。可以到邮件供应商的设置页面找POP3或IMAP这些关键词找到对应的获取位置

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xoNWzlaH-1647010003104)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220311172742214.png)]

  1. 开启定时任务功能
@Service
//将发送邮件的必要信息(发件人、收件人、标题、正文)封装到SimpleMailMessage对象中,可以根据规则设置发送人昵称等。
public class SendMailServiceImpl implements SendMailService {
    @Autowired
    private JavaMailSender javaMailSender;

    //发送人
    private String from = "[email protected]";
    //接收人
    private String to = "[email protected]";
    //标题
    private String subject = "测试邮件";
    //正文
    private String context = "测试邮件正文内容";

    @Override
    public void sendMail() {
        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom(from+"(小甜甜)");
        message.setTo(to);
        message.setSubject(subject);
        message.setText(context);
        javaMailSender.send(message);
    }
}
发送多部件文件

· 发送简单邮件仅需要提供对应的4个基本信息就可以了,如果想发送复杂的邮件,需要更换邮件对象。使用MimeMessage可以发送特殊的邮件。

  1. 发送网页正文邮件
@Service
public class SendMailServiceImpl2 implements SendMailService {
    @Autowired
    private JavaMailSender javaMailSender;

    //发送人
    private String from = "[email protected]";
    //接收人
    private String to = "[email protected]";
    //标题
    private String subject = "测试邮件";
    //正文
    private String context = "点开有惊喜";

    public void sendMail() {
        try {
            MimeMessage message = javaMailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(message);
            helper.setFrom(to+"(小甜甜)");
            helper.setTo(from);
            helper.setSubject(subject);
            helper.setText(context,true);		//此处设置正文支持html解析

            javaMailSender.send(message);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
  1. 发送带有附件的邮件
@Service
public class SendMailServiceImpl2 implements SendMailService {
    @Autowired
    private JavaMailSender javaMailSender;

    //发送人
    private String from = "[email protected]";
    //接收人
    private String to = "[email protected]";
    //标题
    private String subject = "测试邮件";
    //正文
    private String context = "测试邮件正文";

    public void sendMail() {
        try {
            MimeMessage message = javaMailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(message,true);		//此处设置支持附件
            helper.setFrom(to+"(xxx)");
            helper.setTo(from);
            helper.setSubject(subject);
            helper.setText(context);

            //添加附件
            File f1 = new File("springboot_23_mail-0.0.1-SNAPSHOT.jar");
            File f2 = new File("resources\\logo.png");

            helper.addAttachment(f1.getName(),f1);
            helper.addAttachment("xxx.png",f2);

            javaMailSender.send(message);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

信息

同步消息

异步消息

JMS

· 一个规范,等同于JDBC规范,提供了与消息服务的相关的API接口

· JMS消息模型

  1. 点对点模型:peer-2-peer,生产者会将消息发送到一个保存消息的容器中,通常使用队列模型,使用队列保存消息。一个队列的消息只能被一个消费者消费,或未被及时消费导致超时。这种模型下,生产者和消费者是一对一绑定的
  2. 发布订阅模型:publish-subscribe,生产者将消息发送到一个保存消息的容器中,也是使用队列模型来保存。但是消息可以被多个消费者消费,生产者和消费者完全独立,相互不需要感知对方的存在。

· JMS消息种类

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kJMD2ilG-1647010003105)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220311193805196.png)]

AMQP

· 一种协议(高级消息队列协议,也是消息代理规范),规范了网络交换的数据格式,兼容JMS

消息模型
  • direct exchange
  • fanout exchange
  • topic exchange
  • headers exchange
  • system exchange

· 目前实现了AMQP协议的消息中间件技术也很多,而且都是较为流行的技术,例如:RabbitMQ、StormMQ、RocketMQ

AMQP消息种类:byte[]

· AMQP在JMS的消息模型基础上又进行了进一步的扩展,除了点对点和发布订阅的模型,开发了几种全新的消息模型,适应各种各样的消息发送。

MQTT

· 消息队列遥测传输,专为笑傲设备设计,是物联网(IOT)生态系统中主要成分之一

Kafka

· Kafka,一种高吞吐量的分布式发布订阅消息系统,提供实时消息功能。

购物订单业务-发送短信

· 业务层接口

public interface OrderService {
    void order(String id);
}

· 业务层实现

@Service
public class OrderServiceImpl implements OrderService {
    @Autowired
    private MessageService messageService;
    
    @Override
    public void order(String id) {
        //一系列操作,包含各种服务调用,处理各种业务
        System.out.println("订单处理开始");
        //短信消息处理
        messageService.sendMessage(id);
        System.out.println("订单处理结束");
        System.out.println();
    }
}

· 表现层服务

@RestController
@RequestMapping("/orders")
public class OrderController {

    @Autowired
    private OrderService orderService;

    @PostMapping("{id}")
    public void order(@PathVariable String id){
        orderService.order(id);
    }
}

–短信处理业务

· 业务层接口

public interface MessageService {
    void sendMessage(String id);
    String doMessage();
}

· 业务层实现

@Service
public class MessageServiceImpl implements MessageService {
    private ArrayList<String> msgList = new ArrayList<String>();

    @Override
    public void sendMessage(String id) {
        System.out.println("待发送短信的订单已纳入处理队列,id:"+id);
        msgList.add(id);
    }

    @Override
    public String doMessage() {
        String id = msgList.remove(0);
        System.out.println("已完成短信发送业务,id:"+id);
        return id;
    }
}

· 表现层服务

@RestController
@RequestMapping("/msgs")
public class MessageController {

    @Autowired
    private MessageService messageService;

    @GetMapping
    public String doMessage(){
        String id = messageService.doMessage();
        return id;
    }
}

ActiveMQ

下载安装

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nwVQt7Fj-1647010003105)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220311195625240.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-csN8WiXS-1647010003105)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220311195916920.png)]

  1. 导入springboot整合ActiveMQ的starter
<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-activemqartifactId>
dependency>
  1. 配置ActiveMQ的服务器地址
spring:
  activemq:
    broker-url: tcp://localhost:61616
  1. 使用JmsMessagingTemplate操作ActiveMQ
@Service
public class MessageServiceActivemqImpl implements MessageService {
    @Autowired
    private JmsMessagingTemplate messagingTemplate;

    @Override
    public void sendMessage(String id) {
        System.out.println("待发送短信的订单已纳入处理队列,id:"+id);
        messagingTemplate.convertAndSend("order.queue.id",id);
    }

    @Override
    public String doMessage() {
        String id = messagingTemplate.receiveAndConvert("order.queue.id",String.class);
        System.out.println("已完成短信发送业务,id:"+id);
        return id;
    }
}
  1. 使用消息监听器在服务器启动后,监听指定位置,当消息出现后,立即消费消息
@Component
public class MessageListener {
    @JmsListener(destination = "order.queue.id")
    @SendTo("order.other.queue.id")
    public String receive(String id){
        System.out.println("已完成短信发送业务,id:"+id);
        return "new:"+id;
    }
}
  1. 切换消息模型由点对点模型到发布订阅模型,修改jms配置即可
spring:
  activemq:
    broker-url: tcp://localhost:61616
  jms:
    pub-sub-domain: true
# pub-sub-domain默认值为false,即点对点模型,修改为true后就是发布订阅模型

RabbitMQ

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WIzIo7CA-1647010003106)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220311202033151.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oNPo8TW5-1647010003106)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220311202802298.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PB3NhR9L-1647010003106)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220311202809863.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qQ6DrLqC-1647010003107)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220311202827189.png)]

整合(direct模型)

· RabbitMQ满足AMQP协议,因此不同的消息模型对应的制作不同,先使用最简单的direct模型开发。

  1. 导入springboot整合amqp的starter,amqp协议默认实现为rabbitmq方案
<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-amqpartifactId>
dependency>
  1. 配置RabbitMQ的服务器地址
spring:
  rabbitmq:
    host: localhost
    port: 5672
  1. 初始化直连模式系统设置
@Configuration
public class RabbitConfigDirect {
    @Bean
    public Queue directQueue(){
        return new Queue("direct_queue");
    }
    @Bean
    public Queue directQueue2(){
        return new Queue("direct_queue2");
    }
    @Bean
    public DirectExchange directExchange(){
        return new DirectExchange("directExchange");
    }
    @Bean
    public Binding bindingDirect(){
        return BindingBuilder.bind(directQueue()).to(directExchange()).with("direct");
    }
    @Bean
    public Binding bindingDirect2(){
        return BindingBuilder.bind(directQueue2()).to(directExchange()).with("direct2");
    }
}
  1. 使用AmqpTemplate操作RabbitMQ
@Service
public class MessageServiceRabbitmqDirectImpl implements MessageService {
    @Autowired
    private AmqpTemplate amqpTemplate;

    @Override
    public void sendMessage(String id) {
        System.out.println("待发送短信的订单已纳入处理队列(rabbitmq direct),id:"+id);
        amqpTemplate.convertAndSend("directExchange","direct",id);
    }
}
  1. 使用消息监听器在服务器启动后,监听指定位置,当消息出现后,立即消费消息
@Component
public class MessageListener {
    @RabbitListener(queues = "direct_queue")
    public void receive(String id){
        System.out.println("已完成短信发送业务(rabbitmq direct),id:"+id);
    }
}

· 使用注解@RabbitListener定义当前方法监听RabbitMQ中指定名称的消息队列

整合(topic模型)

  1. 同上
  2. 同上
  3. 初始化主题模式系统设置
@Configuration
public class RabbitConfigTopic {
    @Bean
    public Queue topicQueue(){
        return new Queue("topic_queue");
    }
    @Bean
    public Queue topicQueue2(){
        return new Queue("topic_queue2");
    }
    @Bean
    public TopicExchange topicExchange(){
        return new TopicExchange("topicExchange");
    }
    @Bean
    public Binding bindingTopic(){
        return BindingBuilder.bind(topicQueue()).to(topicExchange()).with("topic.*.id");// 主题模式支持routingKey匹配模式,*表示匹配一个单词,#表示匹配任意内容,这样就可以通过主题交换机将消息分发到不同的队列中	
    }
    @Bean
    public Binding bindingTopic2(){
        return BindingBuilder.bind(topicQueue2()).to(topicExchange()).with("topic.orders.*");
    }
}
  1. 使用AmqpTemplate操作RabbitMQ
@Service
public class MessageServiceRabbitmqTopicImpl implements MessageService {
    @Autowired
    private AmqpTemplate amqpTemplate;

    @Override
    public void sendMessage(String id) {
        System.out.println("待发送短信的订单已纳入处理队列(rabbitmq topic),id:"+id);
        amqpTemplate.convertAndSend("topicExchange","topic.orders.id",id);
    }
}
匹配键 topic.*.* topic.#
topic.order.id true true
order.topic.id false false
topic.sm.order.id false true
topic.sm.id false true
topic.id.order true true
topic.id false true
topic.order false true

· 主题模式支持routingKey匹配模式,*表示匹配一个单词,#表示匹配任意内容,这样就可以通过主题交换机将消息分发到不同的队列中

· 发送消息后,根据当前提供的routingKey与绑定交换机时设定的routingKey进行匹配,规则匹配成功消息才会进入到对应的队列中。

  1. 使用消息监听器在服务器启动后,监听指定队列
@Component
public class MessageListener {
    @RabbitListener(queues = "topic_queue")
    public void receive(String id){
        System.out.println("已完成短信发送业务(rabbitmq topic 1),id:"+id);
    }
    @RabbitListener(queues = "topic_queue2")
    public void receive2(String id){
        System.out.println("已完成短信发送业务(rabbitmq topic 22222222),id:"+id);
    }
}

· 使用注解@RabbitListener定义当前方法监听RabbitMQ中指定名称的消息队列。

总结

  1. springboot整合RabbitMQ提供了AmqpTemplate对象作为客户端操作消息队列
  2. 操作ActiveMQ需要配置ActiveMQ服务器地址,默认端口5672
  3. 企业开发时通常使用监听器来处理消息队列中的消息,设置监听器使用注解@RabbitListener
  4. RabbitMQ有5种消息模型,使用的队列相同,但是交换机不同。交换机不同,对应的消息进入的策略也不同

RocketMQ

安装和下载

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DbashaRV-1647010003107)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220311205219596.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ND7RMaLR-1647010003107)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220311210026957.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Qzs4KfCO-1647010003108)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220311210049208.png)]

整合RocketMQ(异步)

  1. 导入springboot整合RocketMQ的starter,此坐标不由springboot维护版本
<dependency>
    <groupId>org.apache.rocketmqgroupId>
    <artifactId>rocketmq-spring-boot-starterartifactId>
    <version>2.2.1version>
dependency>
  1. 配置RocketMQ的服务器地址
rocketmq:
  name-server: localhost:9876
  producer:
    group: group_rocketmq
  1. 设置默认的生产者消费者所属组group,使用RocketMQTemplate操作RocketMQ
@Service
public class MessageServiceRocketmqImpl implements MessageService {
    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Override
    public void sendMessage(String id) {
        System.out.println("待发送短信的订单已纳入处理队列(rocketmq),id:"+id);
        SendCallback callback = new SendCallback() {
            @Override
            public void onSuccess(SendResult sendResult) {
                System.out.println("消息发送成功");
            }
            @Override
            public void onException(Throwable e) {
                System.out.println("消息发送失败!!!!!");
            }
        };
        rocketMQTemplate.asyncSend("order_id",id,callback);
    }
}

  1. 使用asyncSend方法发送异步消息,使用消息监听器在服务器启动后,监听指定位置,当消息出现后,立即消费消息
@Component
@RocketMQMessageListener(topic = "order_id",consumerGroup = "group_rocketmq")
public class MessageListener implements RocketMQListener<String> {
    @Override
    public void onMessage(String id) {
        System.out.println("已完成短信发送业务(rocketmq),id:"+id);
    }
}

· RocketMQ的监听器必须按照标准格式开发,实现RocketMQListener接口,泛型为消息类型。

· 使用注解@RocketMQMessageListener定义当前类监听RabbitMQ中指定组、指定名称的消息队列。

总结

  1. springboot整合RocketMQ使用RocketMQTemplate对象作为客户端操作消息队列
  2. 操作RocketMQ需要配置RocketMQ服务器地址,默认端口9876
  3. 企业开发时通常使用监听器来处理消息队列中的消息,设置监听器使用注解@RocketMQMessageListener

Kafka

安装和下载

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bE59pDsP-1647010003108)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220311211910506.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lAVvdTdw-1647010003108)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220311211936042.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kJ1kDmIB-1647010003109)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220311211953233.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BicJKsOH-1647010003109)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220311212251641.png)]

整合Kafka

  1. 导入springboot整合Kafka的starter,此坐标由springboot维护版本
<dependency>
    <groupId>org.springframework.kafkagroupId>
    <artifactId>spring-kafkaartifactId>
dependency>
  1. 配置Kafka的服务器地址
spring:
  kafka:
    bootstrap-servers: localhost:9092
    consumer:
      group-id: order
      # 设置默认的生产者消费者所属组id
  1. 使用KafkaTemplate操作Kafka
@Service
public class MessageServiceKafkaImpl implements MessageService {
    @Autowired
    private KafkaTemplate<String,String> kafkaTemplate;

    @Override
    public void sendMessage(String id) {
        System.out.println("待发送短信的订单已纳入处理队列(kafka),id:"+id);
        kafkaTemplate.send("itheima2022",id);
        //使用send方法发送消息,需要传入topic名称
    }
}
  1. 使用消息监听器在服务器启动后,监听指定位置,当消息出现后,立即消费消息
@Component
public class MessageListener {
    @KafkaListener(topics = "itheima2022")
    //使用注解@KafkaListener定义当前方法监听Kafka中指定topic的消息,接收到的消息封装在对象ConsumerRecord中,获取数据从ConsumerRecord对象中获取即可
    public void onMessage(ConsumerRecord<String,String> record){
        System.out.println("已完成短信发送业务(kafka),id:"+record.value());
    }
}

总结

  1. springboot整合Kafka使用KafkaTemplate对象作为客户端操作消息队列

  2. 操作Kafka需要配置Kafka服务器地址,默认端口9092

  3. 企业开发时通常使用监听器来处理消息队列中的消息,设置监听器使用注解@KafkaListener。接收消息保存在形参ConsumerRecord对象中

监控

监控的意义

· 监控服务状态是否处理宕机状态

· 监控服务运行指标(内存、虚拟机、线程、请求等)

· 监控程序运行日志

· 管理服务状态

监控的实施方式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zRTpNlQT-1647010003109)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220311213847908.png)]

可视化监控平台

· Spring Boot Admin,这是一个开源社区项目,用于管理和监控SpringBoot应用程序。这个项目中包含有客户端和服务端两部分,而监控平台指的就是服务端

· 服务端开发

  1. 导入springboot admin对应的starter,版本与当前使用的springboot版本保持一致,并将其配置成web工程
<dependency>
    <groupId>de.codecentricgroupId>
    <artifactId>spring-boot-admin-starter-serverartifactId>
    <version>2.5.4version>
dependency>

<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-webartifactId>
dependency>

· 上述过程可以通过创建项目时使用勾选的形式完成

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6rJLy1GA-1647010003110)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220311220241754.png)]

  1. 在引导类上添加注解@EnableAdminServer,声明当前应用启动后作为SpringBootAdmin的服务器使用
@SpringBootApplication
@EnableAdminServer
public class Springboot25AdminServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(Springboot25AdminServerApplication.class, args);
    }
}

· 做到这里,这个服务器就开发好了,启动后就可以访问当前程序了,界面如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8SmfpFJb-1647010003110)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220311220315536.png)]

· 由于目前没有启动任何被监控的程序,所以里面什么信息都没有。下面制作一个被监控的客户端程序

· 客户端开发

  1. 导入springboot admin对应的starter,版本与当前使用的springboot版本保持一致,并将其配置成web工程
<dependency>
    <groupId>de.codecentricgroupId>
    <artifactId>spring-boot-admin-starter-clientartifactId>
    <version>2.5.4version>
dependency>

<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-webartifactId>
dependency>

· 上述过程也可以通过创建项目时使用勾选的形式完成,不过一定要小心,端口配置成不一样的,否则会冲突。

  1. 设置当前客户端将信息上传到哪个服务器上,通过yml文件配置
spring:
  boot:
    admin:
      client:
        url: http://localhost:8080

· 做到这里,这个客户端就可以启动了。启动后再次访问服务端程序,界面如下·

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PL7OuTRp-1647010003110)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220311220421127.png)]

· 可以看到,当前监控了1个程序,点击进去查看详细信息

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2X29Um3S-1647010003111)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220311220434286.png)]

由于当前没有设置开放哪些信息给监控服务器,所以目前看不到什么有效的信息。下面需要做两组配置就可以看到信息了

  1. 开放指定信息给服务器看
  2. 允许服务器以HTTP请求的方式获取对应的信息

​ 配置如下:

server:
  port: 80
spring:
  boot:
    admin:
      client:
        url: http://localhost:8080
management:
  endpoint:
    health:
      show-details: always
  endpoints:
    web:
      exposure:
        include: "*" # 使用*表示查阅全部

· 通过配置就可以开放所有的健康信息明细查看了

management:
  endpoint:
    health:
      show-details: always

总结

  1. 开发监控服务端需要导入坐标,然后在引导类上添加注解@EnableAdminServer,并将其配置成web程序即可
  2. 开发被监控的客户端需要导入坐标,然后配置服务端服务器地址,并做开放指标的设定即可
  3. 在监控平台中可以查阅到各种各样被监控的指标,前提是客户端开放了被监控的指标

监控原理

Actuator

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RQzNqJLC-1647010003111)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220311221337800.png)]

ID 描述 默认启用
auditevents 暴露当前应用程序的审计事件信息。
beans 显示应用程序中所有 Spring bean 的完整列表。
caches 暴露可用的缓存。
conditions 显示在配置和自动配置类上评估的条件以及它们匹配或不匹配的原因。
configprops 显示所有 @ConfigurationProperties 的校对清单。
env 暴露 Spring ConfigurableEnvironment 中的属性。
flyway 显示已应用的 Flyway 数据库迁移。
health 显示应用程序健康信息
httptrace 显示 HTTP 追踪信息(默认情况下,最后 100 个 HTTP 请求/响应交换)。
info 显示应用程序信息。
integrationgraph 显示 Spring Integration 图。
loggers 显示和修改应用程序中日志记录器的配置。
liquibase 显示已应用的 Liquibase 数据库迁移。
metrics 显示当前应用程序的指标度量信息。
mappings 显示所有 @RequestMapping 路径的整理清单。
scheduledtasks 显示应用程序中的调度任务。
sessions 允许从 Spring Session 支持的会话存储中检索和删除用户会话。当使用 Spring Session 的响应式 Web 应用程序支持时不可用。
shutdown 正常关闭应用程序。
threaddump 执行线程 dump。
heapdump 返回一个 hprof 堆 dump 文件。
jolokia 通过 HTTP 暴露 JMX bean(当 Jolokia 在 classpath 上时,不适用于 WebFlux)。
logfile 返回日志文件的内容(如果已设置 logging.file 或 logging.path 属性)。支持使用 HTTP Range 头来检索部分日志文件的内容。
prometheus 以可以由 Prometheus 服务器抓取的格式暴露指标。

· 启用指定端点

management:
  endpoint:
    health:						# 端点名称
      show-details: always
    info:						# 端点名称
      enabled: true				# 是否开放

· 启用所有端点

management:
  endpoints:
    enabled-by-default: true	# 是否开启默认端点,默认值true

· 暴露端点功能

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-voUGFBPk-1647010003111)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220311221642665.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XOMa0HBf-1647010003112)(C:\Users\maybe3032\AppData\Roaming\Typora\typora-user-images\image-20220311221657519.png)]

自定义监控指标

info端点指标控制

· info端点描述了当前应用的基本信息,可以通过两种形式快速配置info端点的信息

  1. 为info端点添加自定义指标(配置模式)
info:
  appName: @project.artifactId@
  version: @project.version@
  company: xxx
  author: itheima
  1. 为info端点添加自定义指标(编程模式)
@Component
public class InfoConfig implements InfoContributor {
    @Override
    public void contribute(Info.Builder builder) {
        builder.withDetail("runTime",System.currentTimeMillis());		//添加单个信息
        Map infoMap = new HashMap();		
        infoMap.put("buildTime","2006");
        builder.withDetails(infoMap);									//添加一组信息
    }
}

Health端点指标控制

· health端点描述当前应用的运行健康指标,即应用的运行是否成功。通过编程的形式可以扩展指标信息

@Component
public class HealthConfig extends AbstractHealthIndicator {
    @Override
    protected void doHealthCheck(Health.Builder builder) throws Exception {
        boolean condition = true;
        if(condition) {
            builder.status(Status.UP);					//设置运行状态为启动状态
            builder.withDetail("runTime", System.currentTimeMillis());
            Map infoMap = new HashMap();
            infoMap.put("buildTime", "2006");
            builder.withDetails(infoMap);
        }else{
            builder.status(Status.OUT_OF_SERVICE);		//设置运行状态为不在服务状态
            builder.withDetail("上线了吗?","你做梦");
        }
    }
}

Metrics端点

· metrics端点描述了性能指标,除了系统自带的监控性能指标,还可以自定义性能指标。

@Service
public class BookServiceImpl extends ServiceImpl<BookDao, Book> implements IBookService {
    @Autowired
    private BookDao bookDao;

    private Counter counter;

    public BookServiceImpl(MeterRegistry meterRegistry){
        counter = meterRegistry.counter("用户付费操作次数:");
    }

    @Override
    public boolean delete(Integer id) {
        //每次执行删除业务等同于执行了付费业务
        counter.increment();
        return bookDao.deleteById(id) > 0;
    }
}

自定义端点

· 可以根据业务需要自定义端点,方便业务监控

@Component
@Endpoint(id="pay",enableByDefault = true)
public class PayEndpoint {
    @ReadOperation
    public Object getPay(){
        Map payMap = new HashMap();
        payMap.put("level 1","300");
        payMap.put("level 2","291");
        payMap.put("level 3","666");
        return payMap;
    }
}

总结

  1. 端点的指标可以自定义,但是每种不同的指标根据其功能不同,自定义方式不同
  2. info端点通过配置和编程的方式都可以添加端点指标
  3. health端点通过编程的方式添加端点指标,需要注意要为对应指标添加启动状态的逻辑设定
  4. metrics指标通过在业务中添加监控操作设置指标
  5. 可以自定义端点添加更多的指标

你可能感兴趣的:(spring,boot,intellij-idea,java)