代码拉取完成,页面将自动刷新
springboot-test1: 测试spring4的泛型注入 封装BaseRepository、BaseService两个模板父类,把通用的crud等代码放在其中,然后子类继承后,只需要添加额外的实现。 如: @Repository class UserRepository extends BaseRepository<User> {...} @Service class UserService extends BaseService<User> {...} controller层调用: @Autowired private UserService userService; springboot-test2: 测试SpringDataJpa使用 主要为复杂查询方法的使用,详情参考“jpa查询方法.txt”文档 1、Specification查询,返回实体、列表、分页 添加exists子查询测试,详见CustomerTest类(注意一对多映射写法) 2、entityManager的原生sql查询,返回实体、列表、分页 3、@Version乐观锁使用 springboot-test3: 测试统一数据格式返回 --测试详情参考《测试用例.postman_collection.json》 1.http日志输出 通过AOP切入:@Aspect @Pointcut @Before @After @AfterReturning @Around 2.统一数据格式返回,格式:{code: xxx, msg: xxx, data: []|{} } 3.统一异常处理 --封装一个业务异常类MyException,使用ResultEnum存放各种异常信息,并使用@ExceptionHandler注解处理捕获的异常。 1、自定义的异常 new MyException(...) 2、访问链接不存在异常(需要在application.properties配置)。 格式:{"code":404,"msg":"找不到系统资源","data":null} 3、系统异常 格式:{"code":-1,"msg":"未知错误","data":null} 4、测试校验异常(MethodArgumentNotValidException)(参考PersonController类) 4.测试多个实体返回(详情参考UserRoleController类) 描述1:统一数据格式里面只能返回一个泛型T的对象,但是我们有时候需要返回两个以上的对象(如有时候会把User对象和Rle对象一起返回)就无能为力了,因此需要处理能返回多个对象的情况。 描述2:有时候我们返回User对象,但是该对象中的password字段不能给,因此需要将User对象转换成vo对象,然后将vo对象返回给前端。 5.entity/list裁剪(详情参考Test4Controller类) 描述:查询DB得到的entity或list是数据库表的所有字段,如果直接将所有字段全部返回给前端,会增加传输压力,而且有些敏感字段也不允许给到前端,因此需要裁剪部分字段。 entity裁剪:User -> UserVo list裁剪: List<User> -> List<UserVo> 6.测试DB更新实体(详情参考Test5Controller类) 描述:前端传部分字段到后端,然后后端通过查询数据库最新记录,再通过反射得到数据库记录与前台实体结合后的实体,jpa直接保存该实体即可 --我们数据库的字段可能很多,但是前端页面能修改的字段可能就几个,jpa的保存机制直接保存整个实体,因此需要保存的应是将前端实体和后端实体结合后得到的实体。如:用户表有用户名、密码、出生日期,但前端仅允许修改用户名、出生日期,因此在保存时将前端传过来的用户名、出生日期,与数据库得到的密码结合,得到新的实体,再保存该新实体。 作用: 1、保证恶意修改其它不必要的字段。保证前端仅能修改的是用户名和出生日期,密码从前端传入无效。 2、部分字段为公共字段,如id、versionNumber、createUser、createTime、lastUpdateUser、lastUpdateTime等,公共字段会抽象成一个类,具体数据库实体继承这些类,从而添加了这些公共字段。在set属性时需要对这一部分字段的赋值。 --附:若仅更新几个字段,可以使用jdbcTemplate进行更新,但这样不能保证jpa的乐观锁是否一致。 7.测试配置文件内容注入(详情参考Test6Controller类) 方式1:Environment形式 方式2:@Value形式 方式3:@ConfigurationProperties形式 8.actuator测试 查看项目状态:http://localhost:8080/actuator/health 查看所有用户:http://localhost:8080/actuator/user --aop版log日志 作用:用于记录当前请求的开始时间、结束时间、token、请求参数、返回参数、异常信息等数据。 实现:统一对Controller层进行增强,针对某些在filter层抛异常返回的可以直接调用一个controller方法也能够进行aop代理,如SpringSecurity的filter可能会不经过controller层。 日志记录:startTime,endTime,url,token,username 日志详细记录:requestObj(由于所有controller方法参数都只有一个,json格式),responseObj,exceptionStack springboot-test4: 测试SpringDataJpa 一对多、多对多关联映射 一对多映射: Customer: //被维护方 @OneToMany(cascade=CascadeType.ALL, mappedBy="customer") private List<Order> orders = new ArrayList<Order>(); Order: //维护方 @ManyToOne @JoinColumn(name="customer_id") private Customer customer; 多对多映射: User: //维护方 @ManyToMany(cascade = CascadeType.ALL) @JoinTable(name = "t_user_role", joinColumns = {@JoinColumn(name = "user_id", referencedColumnName = "id")}, inverseJoinColumns = {@JoinColumn(name = "role_id", referencedColumnName = "id")}) private List<Role> roles = new ArrayList<Role>(); Role: //被维护方 @ManyToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="roles") private List<User> users = new ArrayList<User>(); 多对多映射操作说明: 若添加维护方记录时,会把被维护方记录及关联表记录一并添加;若添加被维护方记录时,能添加本身记录及维护方记录,不产生关联表记录。 若删除维护方记录时,会把被维护方记录及关联表记录一并删除;若删除被维护方记录时,仅删除本身记录。 springboot-test5: 测试SpringDataJpa 自定义Repository 前言: 项目中删除可能仅是逻辑删除(不删除数据库记录),因此需要重写delete()方法,一般都会自己实现RepositoryFactoryBean和Repository 项目中的实体表可能存在公共属性,如主键id、版本号、创建时间、创建人、最后更新时间、最后更新人等。 自定Repository步骤: 1、创建存放公共属性的父类实体 2、创建自定义Repository接口(BaseDao),继承JpaRepository和JpaSpecificationExecutor接口 3、创建BaseDao接口实现类(BaseDaoImpl),继承SimpleJpaRepository类 4、创建自定义BaseDaoFactoryBean类,继承JpaRepositoryFactoryBean类,用来代替默认的RepositoryFactoryBean 5、在SpringBoot启动类注入BaseDaoFactoryBean类 simple-shiro-test: shiro简单认证和授权 realm的用法:SimpleAccountRealm、IniRealm、JdbcRealm、自定义Realm 详情参考“shiro笔记.txt”文档 springboot-test6: 测试shiro整合 对应实体:用户表User、角色表Role、权限表Permission、菜单表Module。user与role关联,role与permission关联,role与module关联,都是多对多关系。 测试账号(在static/db_shiro.sql导入):admin/admin user1/user1 user2/user 分别对这三个账号进行登录,能查看到对应的权限 --整合EhCache springboot-test7: 测试shiro整合 --项目来源于springboot-test6,新整合了密码加密(CredentialsMatcher)、记住我(RememberMeManager)、自定义filter 配置admin账号拥有所有角色及权限。 --后续整合部分:1、会话管理器SessionManager,用于处理集群的session共享问题(使用redis) 2、缓存管理器CacheManager(使用redis) 重写SessionManager时,需要注意retrieveSession方法会执行多少次。 springboot-test8: 测试springboot整合redis 1、测试使用redisTemplate。详情查看UserTest和ListUserTest两个类 2、使用springCache缓存注解,注入具体缓存方案是redis。测试详情查看UserController类。目前设置有效时间为10秒,可设置从配置文件写入 @Cacheable:缓存查询。先从缓存中查询有无数据,有则直接返回,无则执行方法并将返回值存入缓存。适用于读数据。 @CachePut:缓存添加。先执行方法,后将返回值存入缓存。适用于写数据 @CacheEvict:缓存清除。先执行方法,后通过key将缓存里的数据删除。适用于删数据 @Caching:构建复杂缓存。 问题:SpringCache不提供失效时间相关配置? redis可实现配置统一过期时间,但是通常不同key的过期时间都是不一样的,但可以通过配置多个CacheName实现。 springboot-test8-v2: 测试springboot整合redis集群 1、整合redis集群测试 springboot-test8-v2: 测试springboot整合redis(redisson分布式锁) 1、使用可重入锁RLock: 1、启动项目-运行Application#main方法; 2、测试-运行TestController#main方法 2、使用原来的redisTemplate 测试String类型的值:http://localhost:8088/test?key=name&value=testAA 返回testAA 测试Object类型的值:http://localhost:8088/addUser?name=testAA&age=23 返回{"name":null,"age":null,"createTime":"2022-11-11 16:48:39"} >>>redisson其它功能: --公平锁(Fair Lock) RLock fairLock = redisson.getFairLock("anyLock"); --读写锁(ReadWriteLock) RReadWriteLock rwlock = redisson.getLock("anyRWLock"); rwlock.readLock().lock(); // 读加锁 rwlock.writeLock().lock(); // 写加锁 --闭锁(CountDownLatch) RCountDownLatch latch = redisson.getCountDownLatch("anyCountDownLatch"); latch.countDown(); latch.await(); latch.trySetCount(1); // 在其他线程或其他JVM里 --信号量(Semaphore) springboot-test9: 设计模式-责任链模式 1.springSecurity的filter。框架里面有一个ProviderManager类,里面存放了所有的filter,会遍历所有filter找到对应支持的token对象。 2.我们的完整校验,会包括通用校验、特殊校验和远程校验 示例: 责任链模式实现支付校验:详情参考《测试用例.txt》 责任链模式+建造者模式: 登录时需要通过【用户名、密码、角色、权限】校验 springboot-test10: 测试传多个参数情况 --前言:@RequestBody只能是一个参数,且不适应user.name这样的传值 自定义HandlerMethodArgumentResolver,使得从页面传进来的user.id, user.name这些字段自动赋值到user对象中 使用:addUser(@FormBean("user") User user, @FormBean("role") Role role) 输入:http://localhost:8080/user/addUser?user.id=111&user.name=AAA&user.type=type1&role.id=222&role.name=BBB 输出:User [id=111, name=AAA, type=type1] Role [id=222, name=BBB] springboot-test11: 测试jpa添加基础字段 数据库基础字段: 主键Id --IdEntity类 乐观锁 --VersionEntity类 创建时间/创建用户/最后更新时间/最后更新用户 --AuditEntity类 @CreateDate、@CreateBy、@LastModifiedDate、@LastModifiedBy四个注解 创建用户字段自动赋值需要实现AuditorAware接口 @EntityListeners(AuditingListener.class) 和 @EnableJpaAuditing 注解 问题:怎么添加预留字段自动赋值,比如创建机构/最后更新机构等字段? 附:这些创建机构/最后更新机构预留字段可用其它方式实现 @PrePersist/@PreRemove/@PostPersist/@PostRemove/@PreUpdate/@PostUpdate/@PostLoad 注解 ApplicationUtils类:获取ApplicationContext和bean方法,获取property属性方法 springboot-test11-v2: 测试jpa添加基础字段(v2版本) 描述: 除了添加创建时间/创建用户/最后更新时间/最后更新用户这些基础字段外,可能还存在其它基础字段,如创建机构/最后更新机构等,在save时同样需要自动赋值。 解决: 使用@PrePersist/@PreUpdate等注解 springboot-test12-part1 && springboot-test12-part2 测试RestTemplate的使用 RestTemplate是Spring提供的用于访问Rest服务的客户端,RestTemplate提供了多种便捷访问远程http服务的方法,能够大大提高客户端的编写效率。 有时候项目中要建立多个微服务,或者把一个大的项目拆分成多个微服务进行解耦,为了方便完成各个微服务之间进行互相调用,Spring封装了http请求模板类RestTemplate 示例: 普通http测试(数字占位符传参) 普通http测试(map传参) Object类型传参,针对请求参数较少 Map类型传参,针对请求参数很多 Map类型传参,针对请求参数很多 Post请求,模拟新增用户-User类型传参 Post请求,模拟新增用户-Map传参 测试连接超时 测试请求超时 springboot-test13: 测试 logback-spring 日志 1.新增TraceIdLogFilter,用于接口日志追踪; 2.新增ThreadPoolExecutorMdcWrapper、CompletableFutureMdcWrapper包装类用于子线程日志传递 测试日志追踪:http://localhost:8080/test/user 测试ThreadPool子线程日志追踪:http://localhost:8080/test/testThreadPool 测试CompletableFuture子线程日志追踪:http://localhost:8080/test/testCompletableFuture 测试CompletableFuture采用自定义线程池时子线程日志追踪:http://localhost:8080/test/testCompletableFuture2 3.springboot添加拦截器 springboot-test14: 测试thymeleaf模板的高级特性 1.公共模块引入 --> 替换原来jsp的taglib引入 2.页面调用Java的静态变量和静态方法 springboot-test15: 测试jpa封装QueryVo和SaveVo!!! 封装成Vo的作用:仅接收需要操作的字段,防止在前端传入其它非操作字段。 1.QueryVo 直接在Vo类生成Specification类,因此不用在service层写。QueryVo参数条件通过@Filter动态织入。详情查询Controller层方法 2、SaveVo 在Vo类接收仅需要修改的字段,不需要修改的字段不会更新。详情查看UserController的save()方法 springboot-test16: 测试表单提交后相关操作 1、表单提交成功:弹出提示语、并关闭当前页面 2、表单提交成功:弹出提示语、并关闭当前页面和刷新父页面 springboot-test17: 测试使用druid数据库连接池 描述:Druid是一个非常好用的数据库连接池,自身带有一个强大的监控工具:DruidMonitor,不仅可以监控数据源和慢查询,还可以监控web应用、url监控、Session监控、Spring监控。 测试:浏览器输入“http://localhost:8080/druid/login.html”,登录用户“druid/druid”,能进入监控工具。 数据库连接池选择: 性能方面:HikariCP > Druid > Tomcat-jdbc > Dbcp > C3p0 1)HikariCP是springboot的默认连接池,目前性能最好。hikariCP的高性能得益于最大限度的避免锁竞争 2)Druid功能最全面,sql拦截、统计数据等,具有良好的扩展性。 开启prepareStatement缓存,即PSCache,对性能会有大概20%的提升 参考文章:https://blog.csdn.net/justlpf/article/details/80728529 官方文档:https://github.com/alibaba/druid/tree/master/druid-spring-boot-starter druid遇到的坑: 生产环境连接池中,将testOnBorrow=false,由于不检查连接是否可用,应用通过getConnection()获取的连接可能不可用。 统计SQL中是用map保存的,sql太多时会导致oom异常。详情:https://github.com/alibaba/druid/issues/1664 springboot-test18-part1 & springboot-test18-part2 : 测试spring session共享(redis缓存) 参考: https://www.cnblogs.com/SimpleWu/p/10118674.html --补充:可使用nginx配置负载均衡,通过请求同一地址进到不同的应用程序中,查看返回数据(未完成) 测试如下: http://localhost:8080/addSession?username=admin //当前端口号:8080 当前sessionId:17973600-84e1-457b-84ba-9adcc6ab3b67 存入Session的值:admin http://localhost:8080/getSession //当前端口号:8080 当前sessionId:17973600-84e1-457b-84ba-9adcc6ab3b67 获取用户名:admin http://localhost:8081/getSession //当前端口号:8081 当前sessionId:17973600-84e1-457b-84ba-9adcc6ab3b67 获取用户名:admin springboot-test19: 测试jdbcTemplate和NamedParameterJdbcTemplate的使用 --适用于仅执行几个字段的写操作、读操作。高效批量、高效更新 --1.jdbcTemplate测试 update() --执行insert、update、delete语句。参数可写成:new Object[] {"testAA", 2} batchUpdate() --执行批量写操作语句。 queryForObject() --1、单列结果查询(驼峰命名的字段也能自动转换) query() --执行批量读操作语句(驼峰命名的字段也能自动转换) --2.NamedParameterJdbcTemplate测试 NamedParameterJdbcTemplate提供了命名参数,用“:x”代替“?”。 namedParameterJdbcTemplate.update(sql, paramMap); 配置springboot默认日志: # logging.level.root=info logging.file=./logs/log.log logging.pattern.file=%d{yyyy/MM/dd-HH:mm} [%thread] %-5level %logger- %msg%n springboot-test20: 测试jwt使用 jwt工具类(JwtUtils):生成token、解析token token生成:String token = HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret); /login --输入username&password,验证通过后返回生成token,在前端本地保存token 校验jwt拦截器: /hello1 --忽略jwt拦截器 /hello2 --测试jwt拦截器,在header中添加token属性 springboot-test21: 测试前端传参实体与数据库实体结合 --该项目引入了commons-beanutils包(已移除,commons-beanutils 1.9.3不安全) --描述: 从前端传入部分字段,从数据库获取部分字段,将上面两个结合后得到新实体,jpa再保存该新实体。 我们数据库的字段可能很多,但是前端页面能修改的字段可能就几个,jpa的保存机制直接保存整个实体,因此需要保存的应是将前端实体和后端实体结合后得到的实体。如:用户表有用户名、密码、出生日期,但前端仅允许修改用户名、出生日期,因此在保存时将前端传过来的用户名、出生日期,与数据库得到的密码结合,得到新的实体,再保存该新实体。 --测试详情参考UserController类 作用: 1、保证恶意修改其它不必要的字段。保证前端仅能修改的是用户名和出生日期,密码从前端传入无效。 2、部分字段为公共字段,如id、versionNumber、createUser、createTime、lastUpdateUser、lastUpdateTime等,公共字段会抽象成一个类,具体数据库实体继承这些类,从而添加了这些公共字段。在set属性时需要对这一部分字段的赋值。 --附:若仅更新几个字段,可以使用jdbcTemplate进行更新,但这样不能保证jpa的乐观锁是否一致。 springboot-test22: 测试WebSocket,向前端推送消息 测试: --1.两个客户端连接 http://localhost:8080/websocket/socket/20 http://localhost:8080/websocket/socket/21 --2.群发推送消息 http://localhost:8080/websocket/socket/push?message=测试群发推送 --3.推送给某人 http://localhost:8080/websocket/socket/push/21?message=推送给21客户 --4.客户端发送消息 浏览器Console中输入:ws.send("测试客户端20"); springboot-test23: 测试定时任务 @EnableScheduling开启任务调度,@Scheduled创建定时任务。 注:这些任务都是使用同一线程。 scheduler-service: 分布式定时任务实现(quartz实现) springboot-test24: 测试不同数据库插入解决分布式事务问题 使用jta来解决多数据源的分布式事务问题(2pc实现) 缺点:不能解决微服务的分布式事务(远程调用失败后处理不了回滚问题) springboot-test25: 测试springboot整合mybatis框架 user表的增删改查操作,exists查询,动态sql查询 根据id查询order信息,附带部分用户信息,最后封装到vo实体里面 打印sql日志 springboot-test25-v2-new: 测试mybatis-plus 2.4.x以上版本改动 测试相关api方法 测试插入/更新操作时的基础字段自动赋值 测试乐观锁版本控制 测试分页查询 springboot-test25-v3: 测试自动生成代码 springboot-test25-v4: 测试雪花算法生成id,一致性hash插入分表 springboot-test26: 测试Api接口文档生成工具(swagger) http://localhost:8080/swagger-ui.html --文档地址 springboot-test26-v2: http://localhost:8080/doc.html --文档地址 springboot-test27: 测试RabbitMQ的广播模型 举例:公众号一样,我每天推文章后,会推送给每个关注用户,他们都可以看到这条消息 广播模型:1、可以有多个队列;2、每个队列都需要绑定交换机;3、每个消费者有自己的队列;4、交换机把消息发送给绑定的所有队列 http://localhost:8080/send --生产消息 springboot-test27-v2: 测试RabbitMQ的5种消息模式(详情参考RabbitMqTest类) 简单模式 工作模式 广播模式 路由模式 主题模式 springboot-test27-v3: 测试死信与延时队列 springboot-test28: 测试Validator校验工具 1、嵌套属性、集合对象校验 2、新增手动校验工具类 3、空字符串时,不做@Pattern校验,只需要在前面添加“^$|”即可。 如:@Pattern(regexp = "^$|^[a-zA-Z0-9]{6,16}$", message = "用户名不包含特殊字符") 4、日期有效性校验 @NotNull、@NotEmpty、@NotBlank区别: @NotNull: CharSequence、Collection、Map和Array对象不能是null, 但可以是空集(size=0); @NotEmpty: CharSequence、Collection、Map和Array对象不能是null,并且相关对象的size大于0; @NotBlank: String不是null,且去除两端空白字符后的长度大于0。 >>>>>>>>测试maven打包(lib、resources分离) 1、pom.xml文件添加build等相关配置 2、项目打包:maven-> 项目-> Lifecycle -> install,打包成功后,能看到target文件,里面包含所有配置信息 3、运行:进入目录target,执行:java -jar -Dloader.path=.,lib springbootTest28.jar 能看到application.yml也生效了,其引用的application-dev.yml也生效了。 遗留问题:mysql中的配置信息分离出来后会不会生效? springboot-test28-v2: 测试项目打包(lib\resources分离) --描述:相比上述配置更优(推荐) 1.pom.xml文件添加build等相关插件 2.项目打包 操作:最右边maven -> 项目 -> Lifecycle -> install 结果:打包成功后,能看到target文件,里面包含了lib目录、resources目录、jar包 3.运行(进入target目录): > java -jar -Dloader.path=resources,lib springboot-test28-v2.jar --另:springboot配置文件引用Linux环境变量 # 1.编辑Linux环境 > vi /etc/profile #在最后一行添加如下内容 export JAVA_PROFILE_ACTIVE=prod > source /etc/profile #使配置文件生效 # 2.springboot环境使用: spring.profiles.active: ${JAVA_PROFILE_ACTIVE:dev} springboot-test28-ioc: 用于测试ioc相关 v1版本 --测试FactoryBean使用 1)通过myFactoryBean获取实现了FactoryBean接口的Bean,则会调用该接口的getObject()方法,获取到真的值。 2)如果通过&myFactoryBean会获取到FactoryBean实例。 v2版本 --测试SpringAOP实现 该案例一共配置了 2个Advice和 1个Interceptor,然后这些配置都是作为ProxyFactoryBean的属性存在的,上文中已经提到FactgoryBean概念,容器在获取ProxyFactoryBean的时候其实是调用其 getObject方法。正式这个调用完成了代理逻辑的编织。 http://www.myexceptions.net/program/1649287.html --未完成!! com.yjy.postProcessor.v1 //测试BeanFactoryPostProcessor com.yjy.postProcessor.v2 //测试BeanFactoryPostProcessor和BeanPostProcessor 结果分析:BeanFactoryPostProcessor 在 bean 实例化之前被调用,注意在 PersonFactoryPostProcessor 的 postProcessBeanFactory 方法中只是修改了 bean 的定义信息,即将 age 值由18改为23,此时 bean 还未实例化。 之后实例化bean,在此过程中,先调用 BeanPostProcessor 实现类中的 postProcessBeforeInitialization 方法,然后调用实现了 InitializingBean接口的 bean 类中的 afterPropertiesSet 方法,如果设置的有 init-method 方法,则也会被调用,最后再调用 BeanPostProcessor 实现类中的 postProcessAfterInitialization 方法。 springboot-test30: 测试自定义Starter springboot-test31-v2 整合elasticsearch7.6.1 描述:(出自狂神说的教程)模拟爬取京东搜索数据,并放入es中,后续通过es获取对应搜索数据 测试: http://localhost:9090/parse/java http://localhost:9090/ --在输入框中输入“java”,点击搜索,能获取到分页后的10条数据 http://localhost:9090/parse/kafka --爬取京东数据并放入es中 http://localhost:9090/ --在输入框中输入“kafka”,点击搜索,能获取到分页后的10条数据 http://localhost:9090/parse/文 http://localhost:9090/ --在输入框中输入“文”,点击搜索,能获取到分页后的10条数据 springboot-test31-v3 整合elasticsearch7.6.1 测试参考:springboot整合elasticsearch7.postman_collection.json SpringDataElasticsearch是Spring提供的一种以Spring Data风格来操作数据存储的方式,它可以避免编写大量的样板代码。 springboot整合ES相关注解: 1)@Document:文档类型,相当于数据库名称 indexName-对应索引库名称(MySQL的库概念);type-对应在索引库中的类型(MySQL的表概念);shards-分片数量,默认为5;replicas-副本数量,默认1。 2)@Id:标记主键 3)@Field:标记字段。 type:默认FieldType.Auto,可以是integer、short、date、text、keyword等。 text-会分词,并建立索引;支持模糊、精确查询,不支持聚合。text用于全文搜索。 keyword-不会分词建立索引;支持模糊、精确查询,支持聚合。keyword用于关键字搜索。 index:是否建立倒排索引,默认true analyzer:分词器名称(如analyzer = "ik_smart"); store:是否存储 springboot-test32: 未整合springboot,RocketMQ简单测试基础案例 com.yjy.test1 --测试producer的三种发送消息方式:同步、异步、单向发送 com.yjy.test2 --测试顺序消息,消息按照“创建-付款-推送-完成”的顺序消费 实现:producer发送消息时,将相同订单号的消息发送到同一队列,利用队列天生顺序的特性保证消息能顺序消费 com.yjy.test3 --测试不同消费组的消费者消费同一topic消息 MqProducer1发送20条消息,MqConsumer1和MqConsumer2各自都能接收到20条记录 com.yjy.test4 --测试同一消费组的消费者消费不同topic的消息 MqProducer1向a_test4_topic1发送20条消息,MqProducer2向a_test4_topic2发送20条消息; MqConsumer1 接收了 a_test4_topic1中队列2和3 的消息,但仅接收了10条消息。 MqConsumer2 接收了 a_test4_topic2中队列0和1 的消息,但仅接收了10条消息。 结论:同一消费组最好消费同一topic的消息 com.yjy.mq.test1 --读写队列数、生产者数、消费者数配置,扩容,缩容问题 1)读写队列数配置 2)写队列数与生产者数配置 3)读队列数与消费者数配置 springboot-test32-v1: 整合RocketMQ,顺序消费 PS:这里属于模拟测试,生产者和消费者都写在一起 测试:先启动 Application 类,在运行 DelayProduceTest#sendDelayMessage() 方法 一般情况下,可以使用订单号、商品号、用户编号,只要订单号在同一队列,通过队列的天生顺序执行,保证消息能顺序消费。 问:一个队列一个消费者,相同的id放同一队列,这样确实能保证消息顺序消费,但是这样会不会消息堆积? 问:顺序消息队列扩容过程中,如何在不停写的情况下,保证消息顺序? 1、成倍扩容,实现扩容前后,同样的key,hash到原队列或新扩容的队列。 2、扩容前,记录旧队列的最大位点 3、对于每个ConsumerGroup,保证旧队列中消息消费完后,再消费新队列(对新队列禁止读操作) springboot-test32-v2: 整合RocketMQ,延时消息 PS:这里属于模拟测试,生产者和消费者都写在一起 延迟时间:messageDelayLevel=1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h level=0级表示不延时,level=1表示1级延时,level=2表示2级延时,以此类推。 messageExt.setDelayTimeLevel(1); // 表示1级延时 测试:先启动 Application 类,在运行 DelayProduceTest#sendDelayMessage() 方法 输出: --测试1:1分钟后消费消息 1、在DelayProduceTest看到: 发送消息:测试延迟消息,时间:2020年12月25日 11:41:48 2、在Application中看到: 接收消息:测试延迟消息,时间:2020年12月25日 11:42:48 3、说明消息在一分钟后才接收到,测试演示消息成功 --测试2:自定义延时时间,90s后消费消息 1、broker.conf配置文件添加,重启roketmq messageDelayLevel=90s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h 2、先运行 Application 类,再运行 DelayProduceTest#sendCustomeDelayMessage() 方法 发送消息:sendCustomeDelayMessage,时间:2020年12月25日 12:00:00 接收消息:sendCustomeDelayMessage,时间:2020年12月25日 12:01:30 springboot-test32-v3: 整合RocketMQ,事务消息 PS:这里属于模拟测试,生产者和消费者都写在一起 先启动 Application 类,再运行 DelayProduceTest#send() 方法 springboot-test32-v4: 整合RocketMQ,削峰 PS:这里属于模拟测试,生产者和消费者都写在一起 先启动 Application 类,再运行 ProduceTest#send() 方法 这里间隔 2s 拉取数据,每次拉取 2条,有 4个队列,所以每次拉取的数据为 2 * 4 = 8 条。 springboot-test32-v4-next1: 整合RocketMQ,消息消费失败延迟频率 失败重试频率:1s 5s 5s 5s 10s 10s 10s 30s 30s 30s 1m 1m 1m 1m 2m 2m 2m 一共通知15次,超过后自动返回成功 context.setDelayLevelWhenNextConsume(retryTime[reconsumeTimes]); springboot-test32-v5: 整合RocketMQ,广播模式 先启动 Application 类,再修改端口号为8081,再启动 Application 类,这样形成两个消费者集群。 通过运行com.yjy.ProduceTest.send发送数据,发现两个消费者都接受到消息。 PS:同一项目修改端口号后启动多个步骤:打开 Run/Debug Configurations -> 选择 启动类 -> allow parallel run springboot-test32-v6:整合RocketMQ,tag使用 测试不同消费组消费不同的tag --依次启动三个项目,和一个发送消息测试方法 Test32ProducerApplication :8080/ Test32Consumer2Application :8082/ Test32Consumer3Application :8083/ com.yjy.OrderProduceTest#testOrder 能看到所有的消息都消费了 springboot-test32-v7:整合RocketMQ,同一组消费组消费同一tag消息 注:rocketmq-spring-boot-starter的版本需要改成2.2.x,之前2.0.x有问题,会导致多个消费者重复消费问题。 测试:先启动两个消费者(消费同一tag),然后启动生产者(向mq发送1000条消息),发现每个消费者各消费500条记录。 springboot-test32-v8:整合RocketMQ,同一组消费组消费不同tag消息 测试:先启动4个消费者(2消费者消费tag1,2消费者消费tag2),再启动生产者(向mq发送500条tag1消息,500条tag2消息) 结果:只有消费者4消费了250条消息,其它消费者不消费。 springboot-test32-v9:整合RocketMQ,多组消费组消费消息 测试:先启动4个消费者(两组消费组,每组有两个消费者),再启动生产者(向mq发送500条tag1消息,500条tag2消息) 消费者分布:查看rocketmq-console-》Consumer-》搜索“v9”查看到两组消费组-》点击“consume detail”查看消费者,能看到一个消费者消费2个队列(一个topic共4个队列) 结果:每个消费者各消费了250条消息 springboot-test32-v10:整个RocketMQ,同一个项目存在多个消费组情况 同一项目里面存在多个消费组,消费组1消费tag1消息,消费组2消费tag2消息,项目里面有三个服务。生产者发送了500条tag1消息和500条tag2消息。项目里面有三个服务,每个服务都有两个消费者(不同消费组各一个),服务1消费了500条消息(消费队列0和1),服务2消费了250条消息(消费队列2),服务3消费了250条消息(消费队列3)。 springboot-test34:测试ShardingJdbc 测试1:往数据库里面插入100条记录(http://localhost:8080/save) select count(*) from ds0.t_order0; select count(*) from ds0.t_order1; select count(*) from ds1.t_order0; select count(*) from ds1.t_order1; 测试2:查看(http://localhost:8080/list) 测试3:分页(http://localhost:8080/page/0) springboot-test34-v2: MyBatis-plus整合sharding-jdbc 测试分库、分表、分库分表、公共表、读写分离 注:shardingJdbc不支持范围查询,sql不能出现范围查询 流程:指定数据库数据源、指定表、指定分片字段、根据分片字段指定分片策略 ### 测试水平分表:course实际表配置 # 1.指定course表的实际表名称 spring.shardingsphere.sharding.tables.course.actual-data-nodes=m1.course_$->{1..2} # 2.指定course表的主键和生成策略 spring.shardingsphere.sharding.tables.course.key-generator.column=cid spring.shardingsphere.sharding.tables.course.key-generator.type=SNOWFLAKE # 3.指定course表的分表策略,如分表字段cid和策略(cid值为偶数添加到cpirse_1表,奇数添加到course_2表) spring.shardingsphere.sharding.tables.course.table-strategy.inline.sharding-column=cid spring.shardingsphere.sharding.tables.course.table-strategy.inline.algorithm-expression=course_$->{cid % 2 + 1} ### 测试水平分表:course实际表配置 # 1.指定course表的实际表名(格式:库名.表名),如m1.course_1,m1.course_2 spring.shardingsphere.sharding.tables.course.actual-data-nodes=m$->{1..2}.course_$->{1..2} # 2.指定course表的主键和生成策略 spring.shardingsphere.sharding.tables.course.key-generator.column=cid spring.shardingsphere.sharding.tables.course.key-generator.type=SNOWFLAKE # 3.指定course表的分表策略,如分表字段cid和策略(cid值为偶数添加到cpirse_1表,奇数添加到course_2表) spring.shardingsphere.sharding.tables.course.table-strategy.inline.sharding-column=cid spring.shardingsphere.sharding.tables.course.table-strategy.inline.algorithm-expression=course_$->{cid % 2 + 1} # 4.指定course表的分库策略,如分库字段user_id和策略(user_id值为奇数添加到m1库,偶数添加到m2库) spring.shardingsphere.sharding.tables.course.database-strategy.inline.sharding-column=user_id spring.shardingsphere.sharding.tables.course.database-strategy.inline.algorithm-expression=m$->{user_id % 2 + 1} springboot-test36: 测试springboot2.3版本新特性:优雅停机功能 # 1.添加配置项 server.shutdown=graceful spring.lifecycle.timeout-per-shutdown-phase=30s # 2.通过命令关闭服务:kill -2 xxxPID springboot2.3以下版本关闭服务:可以发送http请求来关闭,但实际上不会等待正在执行的程序,而是会直接关闭,还应该配置Tomcat容器相关类(实现TomcatConnectorCustomizer接口)。 curl -X POST http://localhost:自定义端口/自定义路径/shutdown 详情:https://www.cnblogs.com/vishun/p/15527810.html springboot-test36-v3:测试优雅停机,打包成docker镜像并推送到远程仓库(dockerfile-maven-plugin插件) # 1.打包docker镜像,并推送到远程仓库 mvn clean package -DskipTests=true dockerfile:build dockerfile:push # 2.登录远程仓库,能查看到对应镜像 https://cr.console.aliyun.com/repository/cn-hangzhou/yjy_namespace/springboot-test36-v3/images # 3.下载远程仓库的docker镜像并启动 docker pull registry.cn-hangzhou.aliyuncs.com/yjy_namespace/springboot-test36-v3 # 4.启动docker容器,传入变量 docker run --name=springboot-test36-v3 -d --restart=always -p 8080:8080 -e "profiles.active=sit" registry.cn-hangzhou.aliyuncs.com/yjy_namespace/springboot-test36-v3 # 5.测试接口 http://localhost:8080/testSleep30s # 5.停止docker应用(等待【测试接口】结束后退出) docker stop --time=30 springboot-test36-v3 # 6.查看最近100条日志 docker logs -f --tail=100 springboot-test36-v3 场景1:测试springboot+docker优雅停机 --先调用/testSleep30s接口,等一会再执行【docker stop --time=30 springboot-test36-v3】,发现docker会等线程执行完再退出 2024-04-24 20:08:20.357 INFO 1 --- [nio-8080-exec-1] com.yjy.controller.Test36Controller : sit testSleep30s start... 2024-04-24 20:08:35.241 INFO 1 --- [extShutdownHook] o.s.b.w.e.tomcat.GracefulShutdown : Commencing graceful shutdown. Waiting for active requests to complete 2024-04-24 20:08:50.357 INFO 1 --- [nio-8080-exec-1] com.yjy.controller.Test36Controller : testSleep30s end... 2024-04-24 20:08:50.394 INFO 1 --- [tomcat-shutdown] o.s.b.w.e.tomcat.GracefulShutdown : Graceful shutdown complete 2024-04-24 20:08:50.419 INFO 1 --- [extShutdownHook] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'applicationTaskExecutor' 其它命令: # 打包docker镜像,修改tag,并推送到远程仓库(win11报错) mvn clean package -DskipTests=true dockerfile:build -Ddockerfile.tag=latest dockerfile:push # 打tag docker tag registry.cn-hangzhou.aliyuncs.com/yjy_namespace/springboot-test36-v3:latest registry.cn-hangzhou.aliyuncs.com/yjy_namespace/springboot-test36-v3:1.0.0 使用docker-compose实现容器编排 # 1.编写docker-compose.yaml文件 # 2.启动容器:docker-compose up -d # 测试jar包后的docker容器启动 1)更新jar包后,将镜像推送到远程仓库; 2)使用docker-compose pull拉取镜像,并使用docker-compose up -d启动容器(无需stop和rm容器,再run启动容器的原生docker启动方式) springboot-jwt 测试springboot整合security、jwt工具 springboot-jwt-v2 测试springboot整合security、jwt工具 1.添加字典表相关 springboot-test37: # 测试actuator 查看actutor接口:http://localhost:8080/actuator/ 查看项目状态:http://localhost:8080/actuator/health 查看所有用户:http://localhost:8080/actuator/user # actuator整合Prometheus http://localhost:8080/actuator/prometheus
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。