[黑马程序员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.自定义端点 

自定义端点

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/194416.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

代理IP可以用于哪些实际场景?遇到问题如何解决

随着互联网的普及和网络应用的广泛使用&#xff0c;代理IP已成为许多人工作和生活中不可或缺的一部分。代理IP可以用于多种实际场景&#xff0c;并在遇到问题时提供有效的解决方案。下面将详细介绍代理IP的实际应用场景及遇到问题时的解决方法。 一、代理IP的实际应用场景 1. 网…

C#,数值计算——插值和外推,径向基函数插值(RBF_interp)的计算方法与源程序

1 文本格式 using System; namespace Legalsoft.Truffer { /// <summary> /// 径向基函数插值 /// Object for radial basis function interpolation using n points in dim /// dimensions.Call constructor once, then interp as many times as desir…

阿里云服务器部署node和npm

目录 1.链接服务器2.找到node 下载地址3获取链接地址4下载到linux5.解压6.重命名 解压后的文件7.配置环境变量7.1复制当前的bin目录7.2vim /etc/profile7.3在按下ESC按键 8.重启环境变量9.输入node10.npm配置加速镜像 1.链接服务器 2.找到node 下载地址 https://nodejs.org/d…

激光雷达毫米波雷达

一.激光雷达 技术指标&#xff1a; 视场角 线数&#xff08;32/64/128&#xff09; 分辨率&#xff08;激光光束夹角越小分辨率越高&#xff0c;0.1度&#xff09; 探测距离&#xff1a;0.3-200m 反射率&#xff08;一般探测10%以上反射率的目标&#xff09; 分类 按照测距方…

JUC下常用的类

一、Semaphore 信号量 new Semaphore(10) 可以把他理解成停车场&#xff0c;最多停10辆车&#xff0c;多个车进来如果满了就去排队&#xff0c;车走了&#xff0c;车位就空出来了&#xff0c;排队的线程就可以进来主要下面2个方法 Acquire获取锁&#xff1a;通过CAS原子性减1&…

算法通关村第一关|链表基础

1. 单链表概念 对于所有的数据结构的基础都是创建增删改查&#xff0c;学习链表重点也是学习链表的五种基本操作。 单向链表就像一个铁链一样&#xff0c;元素之间相互连接&#xff0c;包含多个结点&#xff0c;每个结点有一个指向后继元素的next指针。表中最后一个元素的nex…

面试常问-如何判断链表有环、?

如何判断链表有环 题目&#xff1a;解决方案一&#xff1a;解决方案二&#xff1a;解决方案三&#xff1a; 题目&#xff1a; 给你一个链表的头节点 head &#xff0c;判断链表中是否有环。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;…

ChromeDriver最新版本下载与安装方法

关于ChromeDriver最新下载地址&#xff1a;https://googlechromelabs.github.io/chrome-for-testing/ 下载与安装 setp1&#xff1a;查看Chrome浏览器版本 首先&#xff0c;需要检查Chrome浏览器的版本。请按照以下步骤进行&#xff1a; 打开Chrome浏览器。 点击浏览器右上角…

7种SQL进阶用法【转】

1.自定义排序(ORDER BY FIELD) 在MySQL中ORDER BY排序除了可以用ASC和DESC之外,还可以使使用自定义排序方式来实现 CREATE TABLE movies ( id INT PRIMARY KEY AUTO_INCREMENT, movie_name VARCHAR(255), actors VARCHAR(255), price DECIMAL(10,2) DEFAULT 50, release date…

文本三剑客(grep,awk,sed)

一.正则表达式 注意事项&#xff1a;使用正则表达式必须加引号。 元字符 表示字符 ① . &#xff1a;在正则表达式中.表示任意单个字符。 [rootpc1 data]#grep -o r.t /etc/passwd #过滤passwd文件中开头为r中间任意单个字符结尾为t的内容 rat rat rat [rootpc1 data]#g…

Open Feign 源码解析(二) --- 如何发送http请求

Open Feign 源码解析二 如何发送http请求&#xff1f; 如何组件化&#xff1f; 定义接口 public interface Client {Response execute(Request request, Options options) throws IOException; }是否存在已有的方案&#xff1f; 1&#xff09;rest template http client o…

《微信小程序开发从入门到实战》学习三十三

第四章 云开发 本章云开发技术的功能与使用&#xff0c;包括以下几点&#xff1a; 1.学习使用云开发控制台 2.学习云开发JSON数据库功能 3.学习云开文件存储功能 4.学习云函数功能 5.使用云开发技术实现投票小程序的服务端功能 投票小程序大部分已经实现。需要实现&#…

【算法萌新闯力扣】:合并两个有序链表

力扣题目&#xff1a;合并两个有序链表 开篇 今天是备战蓝桥杯的第24天及算法村开营第2天。根据算法村的讲义&#xff0c;来刷链表的相关题目。今天要分享的是合并两个有序链表。 题目链接: 21.合并两个有序链表 题目描述 代码思路 通过创建一个新链表&#xff0c;然后遍历…

振南技术干货集:znFAT 硬刚日本的 FATFS 历险记(7)

注解目录 1、znFAT 的起源 1.1 源于论坛 &#xff08;那是一个论坛文化兴盛的年代。网友 DIY SDMP3 播放器激起了我的兴趣。&#xff09; 1.2 硬盘 MP3 推了我一把 &#xff08;“坤哥”的硬盘 MP3 播放器&#xff0c;让我深陷 FAT 文件系统不能自拔。&#xff09; 1.3 我…

Android Bitmap 模糊效果实现 (二)

文章目录 Android Bitmap 模糊效果实现 (二)使用 Vukan 模糊使用 RenderEffect 模糊使用 GLSL 模糊RS、Vukan、RenderEffect、GLSL 效率对比 Android Bitmap 模糊效果实现 (二) 本文首发地址 https://blog.csdn.net/CSqingchen/article/details/134656140 最新更新地址 https:/…

将用户的session改为分布式共享session

将用户的session改为分布式session 分布式session理解 使用分布式session的原因&#xff1a; 后台服务器是分布式的&#xff08;比如要负载均衡&#xff09;&#xff0c;在A服务器请求的的信息&#xff08;如用户登录信息&#xff09;存在A的session中&#xff0c;B服务器并不…

C++之哈希

unordered系列容器的效率之所以比较高(尤其是查找),是因为它底层使用了哈希结构,即哈希表. 哈希概念 前言: 顺序结构以及平衡树中, 元素关键码与其存储位置之间没有对应的关系, 因此在查找一个元素 时, 必须要经过关键码的多次比较. 顺序查找时间复杂度为O(N), 平衡树中为树的…

香港科技大学广州|智能制造学域博士招生宣讲会—天津大学专场

时间&#xff1a;2023年12月07日&#xff08;星期四&#xff09;15:30 地点&#xff1a;天津大学卫津路校区26楼B112 报名链接&#xff1a;https://www.wjx.top/vm/mmukLPC.aspx# 宣讲嘉宾&#xff1a; 汤凯教授 学域主任 https://facultyprofiles.hkust-gz.edu.cn/faculty-p…

解决:AttributeError: module ‘os’ has no attribute ‘mknod’

解决&#xff1a;AttributeError: module ‘os’ has no attribute ‘mknod’ 文章目录 解决&#xff1a;AttributeError: module os has no attribute mknod背景报错问题报错翻译报错位置代码报错原因解决方法今天的分享就到此结束了 背景 在使用之前的代码时&#xff0c;报错…

借助arthas 性能调优全过程

使用 arthas 的trace 命令分析方法耗时瓶颈&#xff1a; 可以看出 bindReloadZoneTimeLimite 耗时最久&#xff0c; 通过分析Bind 底层&#xff0c;将业务粒度进行拆分&#xff0c;加入并发执行 再次使用arthas 追踪单个方法耗时时间&#xff1a; 核心耗时方法&#xff0c…