• 开发实用篇——整合常用的第三方技术


    缓存

    • 介于数据永久存储与数据应用之间的数据临时存储介质
    • 可以有效减少低速数据读取过程的次数,提高系统性能

    启用spring默认缓存技术

    • 导入依赖
     
     <dependency>
         <groupId>org.springframework.bootgroupId>
         <artifactId>spring-boot-starter-cacheartifactId>
     dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 启动类上添加注解
    @SpringBootApplication
    // 开启缓存
    @EnableCaching
    public class CacheApplication {
    
        public static void main(String[] args) {
            System.out.println(Arrays.toString(args));
            SpringApplication.run(CacheApplication.class, args);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 业务层添加注解(value相当于一个命名空间,key必须是唯一的变量
        @Override
        // 使用缓存
        @Cacheable(value = "cacheSpace",key = "#id")
        public Book getById(Integer id) {
            return bookDao.selectById(id);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    手机验证码案例(整合其他缓存技术)

    在这里插入图片描述

    Simple缓存

    • 工具类验证码加密
    @Component
    public class CodeUtils {
    
        private String[] bu = {"00000","0000","000","00","0",""};
    
        public String generator(String tele){
            int hash = tele.hashCode();
            int encryption = 20206666;
            long result = hash^encryption;
            long nowTime = System.currentTimeMillis();
            result = result^nowTime;
            long code =  result % 1000000;
            code = code<0 ? -code : code;
            String codeStr = code + "";
            int length = codeStr.length();
            return bu[length-1]+codeStr;
        }
    
        @Cacheable(value = "smsCode",key = "#tele")
        public String get(String tele){
            return null;
        }
    
        public static void main(String[] args) {
            CodeUtils codeUtils = new CodeUtils();
            String generator = codeUtils.generator("18771496933");
            System.out.println(generator);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • domain
    @Data
    public class SMSCode {
        private String tele;
        private String code;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • controller
    @RestController
    @RequestMapping("/sms")
    public class SMSCodeController {
    
        @Autowired
        private SMSCodeService service;
    
    
        @GetMapping
        public String getCode(String tele){
            String s = service.sendCodeToSMS(tele);
            return s;
        }
    
        @PostMapping
        public boolean checkCode(SMSCode smsCode){
            Boolean code = service.checkCode(smsCode);
            return code;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 业务层
    public interface SMSCodeService {
    
        public String sendCodeToSMS(String tele);
    
        public Boolean checkCode(SMSCode smsCode);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    @Service
    public class SMSServiceImpl implements SMSCodeService {
    
        @Autowired
        private CodeUtils codeUtils;
    
        @Override
        //@Cacheable(value = "smsCode",key = "#tele") 读和写
        @CachePut(value = "smsCode",key = "#tele") // 只写不读
        public String sendCodeToSMS(String tele) {
            String code = codeUtils.generator(tele);
            return code;
        }
    
        @Override
        public Boolean checkCode(SMSCode smsCode) {
            String code = smsCode.getCode();
            String cacheCode = codeUtils.get(smsCode.getTele());
            return cacheCode.equals(code);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    Redis

    • 导入依赖
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-data-redisartifactId>
            dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 配置文件
    spring:
      datasource:
        druid:
          driver-class-name: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC
          username: root
          password: 123456
      cache:
        type: redis
        redis:
          use-key-prefix: true
          cache-null-values: false
          time-to-live: 10s
          key-prefix: ssm_
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    ehcache

    • 只用加进来技术接口是统一的
    <dependency>
        <groupId>net.sf.ehcachegroupId>
        <artifactId>ehcacheartifactId>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 配置文件
    spring:
      datasource:
        druid:
          driver-class-name: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC
          username: root
          password: 123456
      cache:
        type: ehcache
        ehcache:
          config: ehcache.xml
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • ehcache.xml
    
    <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
             updateCheck="false">
        <diskStore path="D:\ehcache" />
    
        
        
        
        
        
        
        
        
        <defaultCache
            eternal="false"
            diskPersistent="false"
            maxElementsInMemory="1000"
            overflowToDisk="false"
            timeToIdleSeconds="60"
            timeToLiveSeconds="60"
            memoryStoreEvictionPolicy="LRU" />
    
        <cache
            name="smsCode"
            eternal="false"
            diskPersistent="false"
            maxElementsInMemory="1000"
            overflowToDisk="false"
            timeToIdleSeconds="10"
            timeToLiveSeconds="10"
            memoryStoreEvictionPolicy="LRU" />
    
    ehcache>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    memcached缓存方案

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述

    jetcache缓存(阿里方案)

    • 对springCache进行了封装,在原有功能基础上实现了多级缓存缓存统计自动刷新异步调用数据报表等功能。
      -在这里插入图片描述

    远程缓存方案

            <dependency>
                <groupId>com.alicp.jetcachegroupId>
                <artifactId>jetcache-starter-redisartifactId>
                <version>2.6.2version>
            dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    jetcache:
      remote:
        default:
          type: redis
          host: localhost
          port: 6379
          poolConfig:
            maxTotal: 50
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    @SpringBootApplication
    // 启用主开关
    @EnableCreateCacheAnnotation
    public class JetCacheApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(JetCacheApplication.class, args);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    @Service
    public class SMSServiceImpl implements SMSCodeService {
    
        @Autowired
        private CodeUtils codeUtils;
    
        @CreateCache(name = "jetCache",expire = 3600,timeUnit = TimeUnit.SECONDS)
        private Cache<String ,String > jetCache;
    
        @Override
        public String sendCodeToSMS(String tele) {
            String code = codeUtils.generator(tele);
            jetCache.put(tele,code);
            return code;
        }
    
        @Override
        public Boolean checkCode(SMSCode smsCode) {
            String code = jetCache.get(smsCode.getTele());
            return smsCode.getCode().equals(code);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    本地缓存

    jetcache:
      remote:
        default:
          type: redis
          host: localhost
          port: 6379
          poolConfig:
            maxTotal: 50
      local:
        default:
          type: linkedhashmap
          keyConvertor: fastjson
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 选择远程还是本地缓存cacheType = CacheType.REMOTE
     @CreateCache(name = "jetCache",expire = 3600,timeUnit = TimeUnit.SECONDS,cacheType = CacheType.REMOTE)
    
    • 1

    方法缓存

    • 配置增加几个配置
    jetcache:
      remote:
        default:
          type: redis
          host: localhost
          port: 6379
          keyConvertor: fastjson
          valueEncode: java
          valueDecode: java
          poolConfig:
            maxTotal: 50
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 实体类上加入一个实现Serializable
    @Data
    public class Book implements Serializable {
        private Integer id;
        private String type;
        private String name;
        private String description;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 方法上面加入注解
        @Override
        @Cached(name = "book",key = "#id",expire = 3600)
        public Book getById(Integer id) {
    
            return bookDao.selectById(id);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    数据淘汰策略

    在这里插入图片描述

    任务

    • 定时任务,常见操作:
      年度报表
      缓存统计报告
      。。。

    quartz定时技术

    相关概念

    在这里插入图片描述

    整合Quartz

    • 导入依赖
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-quartzartifactId>
            dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 定义任务(继承QuartzJobBean )
    public class MyQuartz extends QuartzJobBean {
        @Override
        protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
            System.out.println("Quartz run ...");
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 定义配置类(将任务包装成工作明细,通过触发器绑定工作明细)
    @Configuration
    public class QuartzConfig {
        @Bean
        public JobDetail printJodDetail(){
            return JobBuilder.newJob(MyQuartz.class).storeDurably().build();
        }
    
        @Bean
        public Trigger printJobTrigger(){
            ScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule("0/5 * * * * ?");
            return TriggerBuilder.newTrigger().forJob(printJodDetail()).withSchedule(scheduleBuilder).build();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 启动系统

    整合springBoot Task

    在这里插入图片描述

    • 启动类加入注解@EnableScheduling
    @SpringBootApplication
    // 启用主开关
    @EnableCreateCacheAnnotation
    @EnableScheduling
    @EnableMethodCache(basePackages = "com.ssc.springboot_17_jetcache")
    public class JetCacheApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(JetCacheApplication.class, args);
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 在要定时执行的方法上面加注解@Scheduled(cron = "0/1 * * * * ?")
    @Component
    public class MyBean {
    
        @Scheduled(cron = "0/1 * * * * ?")
        public void print(){
            System.out.println("哈哈哈哈。。。");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    邮件

    • SMTP:简单邮件传输协议,用于发送电子邮件的传输协议
    • POP3:用于接收电子邮件的标准协议
    • IMAP:互联网消息协议,是POP3的替代协议

    程序实现

    • 配置邮箱
    spring:
      mail:
        host: smtp.qq.com
        username: 2683885184@qq.com
        password: wpumbmnpejxddigi # 授权码
        default-encoding: utf-8 #这个是字符集,咱们用utf-8就可以了
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 书写业务层传入mail信息
    public interface SendMailService {
        void sendMail();
    }
    
    • 1
    • 2
    • 3
    @Service
    public class SendMailServiceImpl implements SendMailService {
    
        @Autowired
        private JavaMailSender javaMailSender;
    
        // 发送人
        private String from = "2683885184@qq.com";
        // 接收人
        private String to = "1667568637@qq.com";
        // 标题
        private String subject = "测试邮件";
        // 正文
        private String context = "收到这封邮件不要慌张,这是学习过程中的测试邮件,可以忽略。。。爱你mua~!";
    
        @Override
        public void sendMail() {
            SimpleMailMessage message = new SimpleMailMessage();
            message.setFrom(from);
            message.setTo(to);
            message.setSubject(subject);
            message.setText(context);
            javaMailSender.send(message);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 测试
    @SpringBootTest
    class MailApplicationTests {
    
    	@Autowired
    	private SendMailService service;
    
    	@Test
    	void contextLoads() {
    		service.sendMail();
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    消息

    • JMS:一个规范,等同于JDBC规范,提供了消息服务相关的API接口
      peer-2-peer:点对点模型,消息发送到一个队列中,队列保存消息,队列消息只能被一个消费者消费或超时
      publish-subscribe:发布订阅模型,消息可以被多个消费者消费,生产者消费者完全独立,不需要感知对方的存在
      在这里插入图片描述
    • JMS实现:ACtiveMQ,Redis,HornetMQ,RabbitMQ,RocketMQ(没有完全遵循JMS协议)

    • AMQP:一种协议(高级消息队列协议,也是消息代理规范)规范网阔交换的数据格式,兼容JMS
      优点:具有跨平台性,服务器供应商,生产者,消费者可以使用不同的语言来实现
      在这里插入图片描述
    • AMQP消息种类:byte[](字节数组形式)
    • AMQP实现:RabbitMQ,StormMQ,RocketMQ

    • MQTT:
      消息队列遥测传输,转为小设备,是物联网生态系统中主要成分之一

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

    监控

    监控的意义

    • 监控服务是否宕机
    • 监控服务运行指标(内存,虚拟机,线程,请求等)
    • 监控日志
    • 管理服务(服务下线)

    可视化监控平台

    服务端

    • 导入依赖
            <dependency>
                <groupId>de.codecentricgroupId>
                <artifactId>spring-boot-admin-starter-adminartifactId>
                <version>2.3.1version>
            dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 配置
    port: 8080
    
    • 1
    • 启动类上加上注解
    @SpringBootApplication
    @EnableAdminServer
    public class Springboot19AdminServerApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(Springboot19AdminServerApplication.class, args);
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    客户端

    • 依赖
            <dependency>
                <groupId>de.codecentricgroupId>
                <artifactId>spring-boot-admin-starter-clientartifactId>
                <version>2.3.1version>
            dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 配置
    spring:
      boot:
        admin:
          client:
            url: http://localhost:8080
    server:
      port: 80
    
    management:
      endpoint:
        health:
          show-details: always
      endpoints:
        web:
          exposure:
            include: "*"
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    监控原理

    • web程序专用端点
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
    • 客户端配置样例(只是对外暴露信息)
    management:
      endpoint:
        health:
          show-details: always
        info: # 单独关闭info信息
          enabled: false
      endpoints:
      	# 开启web访问功能
        web:
          exposure:
            include: "*"
        enabled-by-default: true
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    Actuator

    • Actuator提供了SpringBoot生产就绪功能,通过端点的配置与访问,获取端点信息
    • 端点提供了一组监控信息,SpringBoot提供多个内置端点,也可以根据需要自定义端点信息
    • 访问当前应用所有端点信息:/actuator
    • 访问端点详细信息:/actuator/端点名称

    • 暴露端点功能
      在这里插入图片描述
      在这里插入图片描述

    自定义监控指标

    info端点指标控制

    在这里插入图片描述

    • 配置
    info:
      verson: project.version
      artifactId: project.artifactId
      author: ssc
    
    • 1
    • 2
    • 3
    • 4
    • 编程
    @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);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    health端点指标控制

    在这里插入图片描述

    • 编程(最好加入真实状态,而不是纯文本
    @Component
    public class HealthConfig extends AbstractHealthIndicator {
        @Override
        protected void doHealthCheck(Health.Builder builder) throws Exception {
            builder.withDetail("runtime",System.currentTimeMillis());
            Map infoMap = new HashMap();
            infoMap.put("buildTime","2006");
            builder.withDetails(infoMap);
            builder.up();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    metrics端点指标控制

    在这里插入图片描述

    自定义端点

    在这里插入图片描述

    @Component
    @Endpoint(id = "pay",enableByDefault = true)
    public class PayEndpoint {
    
        @ReadOperation
        public void getPay(){
            System.out.println("============");
            System.out.println("============");
            System.out.println("============");
            System.out.println("============");
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
  • 相关阅读:
    Linux用gzip打包压缩和解压文件夹
    【JavaScript】DOM查询(子节点、父节点、兄弟节点)源码详解
    响应式的 switchboard:让又大又慢的Vue/AIpine 页面爆快
    C++ functional库中的仿函数
    管理与系统思维
    Vue配置代理学习笔记
    《Qt-OpenGL系列编程》课程学习记录(10):冯氏光照模型
    SpringBoot2.0数据访问之整合数据源(Druid)
    Centos7构建LNMP平台
    【项目】扫雷小游戏(C语言)
  • 原文地址:https://blog.csdn.net/qq_44808710/article/details/126279623