[黑马程序员SpringBoot2]——开发实用篇3

目录:

  1. jetcache远程缓存方案
  2. jetcache本地缓存方案
  3. jetcache方法缓存
  4. j2cache基本操作
  5. springboot整合quartz​​​​​​​
  6. springboot整合task
  7. 发送简单邮件
  8. 发送多部件邮件
  9. 消息简介
  10. 购物订单案例-发送短信
  11. ActiveMQ安装
  12. springboot整合ActiveMQ
  13. RabbitMQ安装
  14. springboot整合RabbitMQ(direct模式)
  15. springboot整合RabbitMQ(topic模式)
  16. RocketMQ安装
  17. springboot整合RockeMQ
  18. Kafka安装
  19. springboot整合Kafka
  20. 监控的意义
  21. SpringBootAdmin
  22. actuator
  23. info端点指标控制
  24. health端点指标控制
  25. metrics端点指标控制
  26. ​​​​​​​自定义端点

1.jetcache远程缓存方案

  • jetCache对SpningCache进行了封装,在原有功能基础上实现了多级缓存、缓存统计、自动刷新、异步调用、数据报表等功能
  • jetcache设定了本地缓存与远程缓存的多级缓存解决方案
  • 本地缓存(local)
    • LlinkedHashMap
    • Caffeine
  • 远程缓存(remote)
    • Redis
    • Tair

加入jetcache坐标

配置远程缓存必要属性

配置本地缓存必要属性

配置范例

配置属性说明

开启jetcache注解支持

声明缓存对象

操作缓存

代码示例:

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.4</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.example</groupId>
    <artifactId>sprintboot_20_jetcache</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>sprintboot_20_jetcache</name>
    <description>sprintboot_20_jetcache</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.3</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.6</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.alicp.jetcache</groupId>
            <artifactId>jetcache-starter-redis</artifactId>
            <version>2.6.2</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <image>
                        <builder>paketobuildpacks/builder-jammy-base:latest</builder>
                    </image>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

application.yml

server:
  port: 8080

mybatis-plus:
  global-config:
    db-config:
      table-prefix: tbl_
      id-type: auto
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl


spring:
  datasource:
    druid:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://localhost:3308/test_db
      username: root
      password: 666666

jetcache:
  remote:
    default:
      type: redis
      host: localhost
      port: 6379
      poolConfig:
        maxTotal: 50
    sms:
      type: redis
      host: localhost
      port: 6379
      poolConfig:
        maxTotal: 50

BookController.class

package com.example.springboot_20_jetcache.controller;

import com.example.springboot_20_jetcache.domain.Book;
import com.example.springboot_20_jetcache.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/books")
public class BookController {
    @Autowired
    private BookService bookService;

    @GetMapping("{id}")
    public Book getById(@PathVariable Integer id) {
        return bookService.getById(id);
    }

    @PostMapping
    public boolean save(@RequestBody Book book) {
        return bookService.save(book);
    }

    @PutMapping
    public boolean update(@RequestBody Book book) {
        return bookService.update(book);
    }

    @DeleteMapping("{id}")
    public boolean delete(@PathVariable Integer id) {
        return bookService.delete(id);
    }

    @GetMapping
    public List<Book> getAll() {
        return bookService.getAll();
    }
}

SMSCodeController.class

package com.example.springboot_20_jetcache.controller;

import com.example.springboot_20_jetcache.domain.SMSCode;
import com.example.springboot_20_jetcache.service.SMSCodeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/sms")
public class SMSCodeController {

    @Autowired
    private SMSCodeService smsCodeService;

    @GetMapping
    public String getCode(String tele) {
        String code = smsCodeService.sendCodeToSMS(tele);
        return code;
    }

    @PostMapping
    public boolean checkCode(SMSCode smsCode) {
        return smsCodeService.checkCode(smsCode);
    }
}

BookDao.interface

package com.example.springboot_20_jetcache.dao;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.springboot_20_jetcache.domain.Book;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface BookDao extends BaseMapper<Book> {
}

Book.class

package com.example.springboot_20_jetcache.domain;

import lombok.Data;

@Data
public class Book {
    private Integer id;
    private String type;
    private String name;
    private String description;
}

SMSCode.class

package com.example.springboot_20_jetcache.domain;

import lombok.Data;

@Data
public class SMSCode {
    private String tele;
    private String code;
}

BookServiceImpl.class

package com.example.springboot_20_jetcache.service.impl;

import com.example.springboot_20_jetcache.dao.BookDao;
import com.example.springboot_20_jetcache.domain.Book;
import com.example.springboot_20_jetcache.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class BookServiceImpl implements BookService {
    @Autowired
    private BookDao bookDao;

    @Override
    public Book getById(Integer id) {
        Book queryBook = bookDao.selectById(id);
        return queryBook;
    }


    @Override
    public boolean save(Book book) {
        return bookDao.insert(book) > 0;
    }

    @Override
    public boolean update(Book book) {
        return bookDao.updateById(book) > 0;
    }

    @Override
    public boolean delete(Integer id) {
        return bookDao.deleteById(id) > 0;
    }

    @Override
    public List<Book> getAll() {
        return bookDao.selectList(null);
    }
}

SMSCodeServiceImpl.class

package com.example.springboot_20_jetcache.service.impl;

import com.alicp.jetcache.Cache;
import com.alicp.jetcache.anno.CreateCache;
import com.example.springboot_20_jetcache.domain.SMSCode;
import com.example.springboot_20_jetcache.service.SMSCodeService;
import com.example.springboot_20_jetcache.utils.CodeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Service
public class SMSCodeServiceImpl implements SMSCodeService {
    @Autowired
    private CodeUtils codeUtils;

    @CreateCache(name = "jetCache", expire = 10, timeUnit = TimeUnit.SECONDS)
    private Cache<String, String> jetCache;

    @CreateCache(area = "sms", name = "jetCache2", expire = 10, timeUnit = TimeUnit.SECONDS)
    private Cache<String, String> jetCache2;

    @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);
    }
}

BookService.interface

package com.example.springboot_20_jetcache.service;


import com.example.springboot_20_jetcache.domain.Book;

import java.util.List;

public interface BookService {
    public boolean save(Book book);

    public Book getById(Integer id);

    public boolean update(Book book);

    public boolean delete(Integer id);

    public List<Book> getAll();
}

SMSCodeService.interface

package com.example.springboot_20_jetcache.service;

import com.example.springboot_20_jetcache.domain.SMSCode;

public interface SMSCodeService {
    public String sendCodeToSMS(String tele);

    public boolean checkCode(SMSCode smsCode);
}

CodeUtils.class

package com.example.springboot_20_jetcache.utils;

import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;

@Component
public class CodeUtils {

    private String[] patch = {"000000", "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 len = codeStr.length();

        return patch[len] + codeStr;
    }


    @Cacheable(value = "smsCode", key = "#tele")
    public String get(String tele) {
        return null;
    }

    public static void main(String[] args) {
        System.out.println(new CodeUtils().generator("15033657967"));
    }
}

Springboot20JetcacheApplication.class

package com.example.springboot_20_jetcache;

import com.alicp.jetcache.anno.config.EnableCreateCacheAnnotation;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@EnableCreateCacheAnnotation
public class Springboot20JetcacheApplication {

    public static void main(String[] args) {
        SpringApplication.run(Springboot20JetcacheApplication.class, args);
    }

}

2.jetcache本地缓存方案

application.yml

server:
  port: 8080

mybatis-plus:
  global-config:
    db-config:
      table-prefix: tbl_
      id-type: auto
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl


spring:
  datasource:
    druid:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://localhost:3308/test_db
      username: root
      password: 666666

jetcache:
  local:
    default:
      type: linkedhashmap
      keyConvertor: fastjson
  remote:
    default:
      type: redis
      host: localhost
      port: 6379
      poolConfig:
        maxTotal: 50
    sms:
      type: redis
      host: localhost
      port: 6379
      poolConfig:
        maxTotal: 50

SMSCodeServiceImpl.class

package com.example.springboot_20_jetcache.service.impl;

import com.alicp.jetcache.Cache;
import com.alicp.jetcache.anno.CacheType;
import com.alicp.jetcache.anno.CreateCache;
import com.example.springboot_20_jetcache.domain.SMSCode;
import com.example.springboot_20_jetcache.service.SMSCodeService;
import com.example.springboot_20_jetcache.utils.CodeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Service
public class SMSCodeServiceImpl implements SMSCodeService {
    @Autowired
    private CodeUtils codeUtils;

//    @CreateCache(name = "jetCache", expire = 10, timeUnit = TimeUnit.SECONDS)
//    private Cache<String, String> jetCache;
//
//    @CreateCache(area = "sms", name = "jetCache2", expire = 10, timeUnit = TimeUnit.SECONDS)
//    private Cache<String, String> jetCache2;


    @CreateCache(name = "jetCache", expire = 1000, timeUnit = TimeUnit.SECONDS,cacheType = CacheType.LOCAL)
    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);
    }
}

3.jetcache方法缓存

启用方法注解

使用方法注解操作缓存

 

缓存对象必须保障可序列化

 

查看缓存统计报告

application.yml

server:
  port: 8080

mybatis-plus:
  global-config:
    db-config:
      table-prefix: tbl_
      id-type: auto
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl


spring:
  datasource:
    druid:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://localhost:3308/test_db
      username: root
      password: 666666

jetcache:
  statIntervalMinutes: 1
  local:
    default:
      type: linkedhashmap
      keyConvertor: fastjson
  remote:
    default:
      type: redis
      host: localhost
      port: 6379
      keyConvertor: fastjson
      valueEncode: java
      valueDecode: java
      poolConfig:
        maxTotal: 50
    sms:
      type: redis
      host: localhost
      port: 6379
      poolConfig:
        maxTotal: 50

BookServiceImpl.class

package com.example.springboot_20_jetcache.service.impl;

import com.alicp.jetcache.anno.*;
import com.example.springboot_20_jetcache.dao.BookDao;
import com.example.springboot_20_jetcache.domain.Book;
import com.example.springboot_20_jetcache.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class BookServiceImpl implements BookService {
    @Autowired
    private BookDao bookDao;

    @Override
    @Cached(area = "default", name = "book", key = "#id", expire = 3600, cacheType = CacheType.REMOTE)
    //    @CacheRefresh(refresh = 5)
    public Book getById(Integer id) {
        Book queryBook = bookDao.selectById(id);
        return queryBook;
    }


    @Override
    public boolean save(Book book) {
        return bookDao.insert(book) > 0;
    }

    @Override
    @CacheUpdate(name = "book", key = "#book.id", value = "#book")
    public boolean update(Book book) {
        return bookDao.updateById(book) > 0;
    }

    @Override
    @CacheInvalidate(name = "book", key = "#id")
    public boolean delete(Integer id) {
        return bookDao.deleteById(id) > 0;
    }

    @Override
    public List<Book> getAll() {
        return bookDao.selectList(null);
    }
}

4.j2cache基本操作

  • j2cache是一个缓存整合框架,可以提供缓存的整合方案,使各种缓存搭配使用,自身不提供缓存功能
  • 基于ehcache + nedis.进行整合

加入j2cache坐标,加入整合缓存的坐标

配置使用j2cache (application.yml)

配置─级缓存与二级缓存以及一级缓存数据到二级缓存的发送方式 (j2cache.properties)

设置使用缓存

 

5.springboot整合quartz

  • 定时任务是企业级应用中的常见操作
    • 年度报表
    • 缓存统计报告
  • 市面上流行的定时任务技术
    • Quartz
    • Spring Task

相关概念

  • 工作 (Job)∶用于定义具体执行的工作
  • 工作明细(JobDetail):用于描述定时工作相关的信息
  • 触发器(Trigger)∶用于描述触发工作的规则,通常使用cron表达式定义调度规则
  • 调度器(Scheduler):描述了工作明细与触发器的对应关系

导入SpringBoot整合quartz的坐标

定义具体要执行的任务,继承QuartzJobBean

定义工作明细与触发器,并绑定对应关系

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.17</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>springboot_22_task</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot_22_task</name>
    <description>springboot_22_task</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-quartz</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <image>
                        <builder>paketobuildpacks/builder-jammy-base:latest</builder>
                    </image>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

QuartzConfig.class

package com.example.springboot_22_task.config;

import com.example.springboot_22_task.quartz.MyQuartz;
import org.quartz.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class QuartzConfig {
    @Bean
    public JobDetail printJobDetail() {
        return JobBuilder.newJob(MyQuartz.class).storeDurably().build();
    }

    @Bean
    public Trigger printJobTrigger() {
        ScheduleBuilder schedBuilder = CronScheduleBuilder.cronSchedule("0/5 * * * * ?");
        return TriggerBuilder.newTrigger().forJob(printJobDetail()).withSchedule(schedBuilder).build();
    }
}

MyQuartz.class

package com.example.springboot_22_task.quartz;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;

public class MyQuartz extends QuartzJobBean {
    @Override
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
        System.out.println("quartz task run...");
    }
}

6.springboot整合task

开启定时任务功能

设置定时执行的任务,并设定执行周期

定时任务相关配置

MyBean.class

package com.example.springboot_22_task.quartz;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class MyBean {
    @Scheduled(cron = "0/1 * * * * ?")
    public void print() {
        System.out.println(Thread.currentThread().getName() + " :spring task run...");
    }
}

Springboot22TaskApplication.class

package com.example.springboot_22_task;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling
public class Springboot22TaskApplication {

    public static void main(String[] args) {
        SpringApplication.run(Springboot22TaskApplication.class, args);
    }

}

application.yml

spring:
  task:
    scheduling:
      thread-name-prefix: spring_tasks_

7.发送简单邮件

  • SMTP (Simple Mail Transfer Protocol):简单邮件传输协议,用于发送电子邮件的传输协议
  • POP3 ( Post Office Protocol - Version 3):用于接收电子邮件的标准协议
  • IMAP ( Internet Mail Access Protocol) :互联网消息协议,是POP3的替代协议

导入SpringBoot整合JavaMail的坐标

配置JavaMail

 

代码示例:

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.17</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>springboot_23_mail</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot_23_mail</name>
    <description>springboot_23_mail</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <image>
                        <builder>paketobuildpacks/builder-jammy-base:latest</builder>
                    </image>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

 SendMailService.interface

package com.example.springboot_23_mail.service;

public interface SendMailService {
    void sendMail();
}

SendMailServiceImpl.class

package com.example.springboot_23_mail.service.impl;

import com.example.springboot_23_mail.service.SendMailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;

@Service
public class SendMailServiceImpl implements SendMailService {

    @Autowired
    private JavaMailSender javaMailSender;

    private String from = "348904@qq.com";

    private String to = "ter@126.com";

    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);
    }
}

Springboot23MailApplicationTests.class

package com.example.springboot_23_mail;

import com.example.springboot_23_mail.service.SendMailService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;


@SpringBootTest
class Springboot23MailApplicationTests {


    @Autowired
    private SendMailService sendMailService;

    @Test
    void contextLoads() {
        sendMailService.sendMail();
    }

}

 application.yml

spring:
  mail:
    username: 3864@qq.com
    password: pn............qcjbc
    host: smtp.qq.com

8.发送多部件邮件

附件与HTML文本支持

SendMailServiceImpl2.class

package com.example.springboot_23_mail.service.impl;

import com.example.springboot_23_mail.service.SendMailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.File;

//@Service
public class SendMailServiceImpl2 implements SendMailService {

    @Autowired
    private JavaMailSender javaMailSender;

    private String from = "344@qq.com";

    private String to = "tar@126.com";

    private String subject = "测试邮件";

    private String context = "<a href='https://www.baidu.com'>点开有惊喜</a>";

    @Override
    public void sendMail() {
        try {
            MimeMessage message = javaMailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            helper.setFrom(from + "(小甜甜)");
            helper.setTo(to);
            helper.setSubject(subject);
            helper.setText(context, true);

            File f1 = new File("D:\\hdc\\test.txt");
            File f2 = new File("D:\\hdc\\test2.txt");
            helper.addAttachment(f1.getName(), f1);
            helper.addAttachment(f2.getName(), f2);

            javaMailSender.send(message);
        } catch (MessagingException e) {
            throw new RuntimeException(e);
        }
    }
}

SendMailServiceImpl3.class

package com.example.springboot_23_mail.service.impl;

import com.example.springboot_23_mail.service.SendMailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.File;

@Service
public class SendMailServiceImpl3 implements SendMailService {

    @Autowired
    private JavaMailSender javaMailSender;

    private String to = "34@qq.com";

    private String from = "ter@126.com";

    private String subject = "测试邮件";

    private String context = "<a href='https://www.baidu.com'>点开有惊喜</a>";

    @Override
    public void sendMail() {
        try {
            MimeMessage message = javaMailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            helper.setFrom(from + "(小甜甜)");
            helper.setTo(to);
            helper.setSubject(subject);
            helper.setText(context, true);

            File f1 = new File("D:\\hdc\\test.txt");
            File f2 = new File("D:\\hdc\\test2.txt");
            helper.addAttachment(f1.getName(), f1);
            helper.addAttachment(f2.getName(), f2);

            javaMailSender.send(message);
        } catch (MessagingException e) {
            throw new RuntimeException(e);
        }
    }
}

application.yml

#spring:
#  mail:
#    username: 34864@qq.com
#    password: pndkzucx
#    host: smtp.qq.com

spring:
  mail:
    username: ter@126.com
    password: HESHJP
    host: smtp.126.com

9.消息简介

企业级应用中广泛使用的三种异步消息传递技术

  • JMS
  • AMQP
  • MQTT

JMS (Java Message Service):一个规范,等同于JDBC规范,提供了与消息服务相关的API接口JMS消息模型

  • peer-2-peer:点对点模型,消息发送到一个队列中,队列保存消息。队列的消息只能被一个消费者消费,或超时
  • publish-subscribe: 发布订阅模型,消息可以被多个消费者消费,生产者和消费者完全独立,不需要感知对方的存在

JMS消息种类

  • TextMessage
  • MapMessage
  • BytesMessage
  • StreamMessage
  • ObjectMessage.
  • Message(只有消息头和属性) 

JMS实现:ActiveMQ、Redis、HornetMQ、RabbitMQ、RocketMQ(没有完全遵守JMS规范)

AMQP 

  • AMQP(advanced message queuing protocol):一种协议(高级消息队列协议,也是消息代理规范),规范了网络交换的数据格式,兼容JMS
  • 优点:具有跨平台性,服务器供应商,生产者,消费者可以使用不同的语言来实现
  • AMQP消息模型
    • direct exchange
    • fanout exchange
    • topic exchange
    • headers exchange
    • system exchange
  • AMQP消息种类: byte[]
  • AMQP实现:RabbitMQ.StormMQ..RocketMQ 

MQTT

MQTT(Message Queueing Telemetry Transport))消息队列遥测传输,专为小设备设计,是物联网(IOT)生态系统中主要成分之一.

Kafka

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

消息

  • ActiveMQ
  • RabbitMQ
  • RocketMQ
  • Kafka

10.购物订单案例-发送短信

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.17</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>springboot_24_mq</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot_24_mq</name>
    <description>springboot_24_mq</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <image>
                        <builder>paketobuildpacks/builder-jammy-base:latest</builder>
                    </image>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

MessageController.class

package com.example.springboot_24_mq.controller;

import com.example.springboot_24_mq.service.MessageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/msgs")
public class MessageController {
    @Autowired
    private MessageService messageService;

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

OrderController.class

package com.example.springboot_24_mq.controller;

import com.example.springboot_24_mq.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/orders")
public class OrderController {
    @Autowired
    private OrderService orderService;

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

MessageServiceImpl.class

package com.example.springboot_24_mq.service.impl;

import com.example.springboot_24_mq.service.MessageService;
import org.springframework.stereotype.Service;

import java.util.ArrayList;

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

    @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;
    }
}

OrderServiceImpl.class

package com.example.springboot_24_mq.service.impl;

import com.example.springboot_24_mq.service.MessageService;
import org.springframework.stereotype.Service;

import java.util.ArrayList;

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

    @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;
    }
}

MessageService.interface

package com.example.springboot_24_mq.service;

public interface MessageService {
    void sendMessage(String id);

    String doMessage();

}

OrderService.interface

package com.example.springboot_24_mq.service;

public interface OrderService {
    void order(String id);

}

application.yml

server:
  port: 8080

11.ActiveMQ安装

  • 下载地址: https://activemq.apache.org/components/classic/download/
  • 安装:解压缩 

启动服务

访问服务器

服务端口:61616,管理后台端口:8161

用户名&密码:admin

12.springboot整合ActiveMQ

导入SpringBoot整合ActiveMQ坐标

配置ActiveMQ(采用默认配置) 

生产与消费消息(使用默认消息存储队列)

生产与消费消息(指定消息存储队列)

使用消息监听器对消息队列监听

流程性业务消息消费完转入下一个消息队列

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.17</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>springboot_24_mq</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot_24_mq</name>
    <description>springboot_24_mq</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-activemq</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <image>
                        <builder>paketobuildpacks/builder-jammy-base:latest</builder>
                    </image>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

 application.yml

server:
  port: 8080


spring:
  activemq:
    broker-url: tcp://localhost:61616
  jms:
    template:
      default-destination: itheima

MessageListener.class

package com.example.springboot_24_mq.service.impl.activemq.listener;

import org.springframework.jms.annotation.JmsListener;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.stereotype.Component;

@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;
    }
}

MessageServiceActivemqImpl.class

package com.example.springboot_24_mq.service.impl.activemq;

import com.example.springboot_24_mq.service.MessageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsMessagingTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;

@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;
    }
}

13.RabbitMQ安装

  • RabbitMQ基于Erlang语言编写,需要安装Erlang
  • Erlang
  • 下载地址: https://www.erlang.org/downloads
  • 安装:一键傻瓜式安装,安装完毕需要重启,需要依赖Windows组件
  • 环境变量配置
    • ERLANG_HOME
    • PATH
  • 下载地址: https://rabbitmq.com/install-windows.html
  • 安装:一键傻瓜式安装

RabbitMQ

启动服务

关闭服务

查看服务状态

服务管理可视化(插件形式)

查看已安装的插件列表 

开启服务管理插件

访问服务器

服务端口:5672,管理后台端口:15672

用户名&密码:guest 

14.springboot整合RabbitMQ(direct模式)

配置RabbitMQ(采用默认配置)

定义消息队列(direct)

生产与消费消息(direct)

使用消息监听器对消息队列监听(direct)

使用多消息监听器对消息队列监听进行消息轮循处理(direct)

15. springboot整合RabbitMQ(topic模式)

定义消息队列(topic)

绑定键匹配规则

  • *(星号):用来表示—个单词,且该单词是必须出现的
  • #(井号):用来表示任意数量 

生产与消费消息(topic)

使用消息监听器对消息队列监听(topic)

16.RocketMQ安装

  • 下载地址: https://rocketmq.apache.org/
  • 安装:解压缩
    • 默认服务端口:9876
  • 环境变量配置
    • ROCKETMQ_HOME
    • PATH
    • NAMESRV_ADDR (建议) : 127.0.0.1:9876

命名服务器与broker

 

 

启动命名服务器

启动broker

服务器功能测试:生产者

服务器功能测试:消费者

17.springboot整合RockeMQ

 导入SpringBoot整合RocketMQ坐标

配置RocketMQ(采用默认配置) 

生产消息

 

生产异步消息

使用消息监听器对消息队列监听

 

18.Kafka安装

  • 下载地址: https://kafka.apache.org/downloads
  • windows系统下3.0.0版本存在BUG,建议使用2.X版本
  • 安装:解压缩 

启动zookeeper

默认端口:2181

启动kafka

默认端口:9092

创建topic

查看topic

册除topic

生产者功能测试

消费者功能测试

 

19.springboot整合Kafka 

导入SpringBoot整合Kafka坐标

配置Kafka(采用默认配置) 

生产消息

使用消息监听器对消息队列监听

 

20.监控的意义

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

监控的实施方式

  • 显示监控信息的服务器:用于获取服务信息,并显示对应的信息
  • 运行的服务:启动时主动上报,告知监控服务器自己需要受到监控 

 

21.SpringBootAdmin

可视化监控平台

  • Spring Boot Admin,开源社区项目,用于管理和监控SpringBoot应用程序。客户端注册到服务端后,通过HTTP请求方式,服务端定期从客户端获取对应的信息,并通过UIl界面展示对应信息。
  • Admin服务端 

 

Admin客户端

 

Admin服务端

 

Admin客户端

Admin服务端

 

设置启用Spring-Admin

Admin客户端

 

 

 22.actuator

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

ID

描述

默认启用

auditevents

暴露当前应用程序的审计事件信息。

beans

显示应用程序中所有 Spring bean 的完整列表。

caches

暴露可用的缓存。

conditions

显示在配置和自动配置类上评估的条件以及它们匹配或不匹配的原因。

configprops

显示所有 @ConfigurationProperties 的校对清单。

env

暴露 Spring ConfigurableEnvironment 中的属性。

flyway

显示已应用的 Flyway 数据库迁移。

health

显示应用程序健康信息

httptrace

显示 HTTP 追踪信息(默认情况下,最后 100 HTTP 请求/响应交换)。

info

显示应用程序信息。

integrationgraph

显示 Spring Integration 图。

 

ID

描述

默认启用

loggers

显示和修改应用程序中日志记录器的配置。

liquibase

显示已应用的 Liquibase 数据库迁移。

metrics

显示当前应用程序的指标度量信息。

mappings

显示所有 @RequestMapping 路径的整理清单。

scheduledtasks

显示应用程序中的调度任务。

sessions

允许从 Spring Session 支持的会话存储中检索和删除用户会话。当使用 Spring Session 的响应式 Web 应用程序支持时不可用。

shutdown

正常关闭应用程序。

threaddump

执行线程 dump

Web程序专用端点

ID

描述

默认启用

heapdump

返回一个 hprof  dump 文件。

jolokia

通过 HTTP 暴露 JMX bean(当 Jolokia classpath 上时,不适用于 WebFlux)。

logfile

返回日志文件的内容(如果已设置 logging.file  logging.path 属性)。支持使用 HTTP Range 头来检索部分日志文件的内容。

prometheus

以可以由 Prometheus 服务器抓取的格式暴露指标。

启用指定端点

启用所有端点

暴露端点功能

  • 端点中包含的信息存在敏感信息,需要对外暴露端点功能时手动设定指定端点信息 

属性

默认

management.endpoints.jmx.exposure.exclude

management.endpoints.jmx.exposure.include

*

management.endpoints.web.exposure.exclude

management.endpoints.web.exposure.include

info, health

 

ID

JMX

Web

auditevents

beans

caches

conditions

configprops

env

flyway

health

heapdump

N/A

httptrace

info

ID

JMX

Web

integrationgraph

jolokia

N/A

logfile

N/A

loggers

liquibase

metrics

mappings

prometheus

N/A

scheduledtasks

sessions

shutdown

threaddump

23.info端点指标控制

为info端点添加自定义指标

24.health端点指标控制

为Health端点添加自定义指标

25.metrics端点指标控制

为Metrics端点添加自定义指标 

26.自定义端点 

自定义端点

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿瞒有我良计15

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值