{"id":24737700,"url":"https://github.com/lctking/buzhoukit","last_synced_at":"2025-10-10T06:31:57.931Z","repository":{"id":270987240,"uuid":"910017269","full_name":"lctking/BuzhouKit","owner":"lctking","description":"幂等-幂等性保证-@Idempotent幂等注解-幂等组件开箱即用 幂等场景支持RestAPI接口\u0026消息队列等等 附详细幂等组件使用说明等","archived":false,"fork":false,"pushed_at":"2025-01-24T10:05:57.000Z","size":153,"stargazers_count":2,"open_issues_count":1,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-24T11:19:42.969Z","etag":null,"topics":["aop","bloom-filter","caffeine-cache","idempotency","redis-cache","spring-boot"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lctking.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-12-30T09:39:31.000Z","updated_at":"2025-01-24T10:06:00.000Z","dependencies_parsed_at":"2025-01-04T16:18:51.470Z","dependency_job_id":"7d879c6f-d684-45a0-bcad-bd40e9c1a4a8","html_url":"https://github.com/lctking/BuzhouKit","commit_stats":null,"previous_names":["lctking/buzhoukit"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lctking%2FBuzhouKit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lctking%2FBuzhouKit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lctking%2FBuzhouKit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lctking%2FBuzhouKit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lctking","download_url":"https://codeload.github.com/lctking/BuzhouKit/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":235929977,"owners_count":19067857,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aop","bloom-filter","caffeine-cache","idempotency","redis-cache","spring-boot"],"created_at":"2025-01-27T22:09:07.215Z","updated_at":"2025-10-10T06:31:51.967Z","avatar_url":"https://github.com/lctking.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# BuzhouKit\n#### A Lightweight Idempotent Component\n\u003e ##### *西北海之外，大荒之隅，有山而不合，名曰不周负子，有两黄兽守之。有水曰寒署之水。水西有湿山，水东有幕山。*  \n\u003e ##### \u003cdiv align=\"right\"\u003e\u003cem\u003e—— 《山海经》海经·大荒西经\u003c/em\u003e\u003c/div\u003e\n#### BuzhouKit，一个轻量级幂等组件库\n## 项目概述\n**BuzhouKit** 是一款专为确保幂等性设计的组件库。简单添加一个注解@Idempotent即可解决幂等问题！此库适用于需要保证操作重复性和一致性的应用场景，为开发者提供一个可靠、稳定的基础设施。  \n### 流程图  \n![image](https://github.com/user-attachments/assets/970fde43-3c62-4101-a285-7c2f12766309)\n\n### 配置/如何使用\n### 1，代码配置  \n##### 方法一（将代码配置到本地maven仓库）  \n1，将代码克隆/下载到本地  \n2，进入到BuZhouKit\\BuZhouKit-Idempotent\u003e目录下运行`mvn clean install`  使得代码保存在本地maven库中，再通过pom坐标即可引用；  \n![image](https://github.com/user-attachments/assets/08d3b4a4-8ea4-48e3-a88e-9e690288c866)  \n![f4a1dfb9c28b938bf79b5a501c003e86](https://github.com/user-attachments/assets/35c1555e-9174-498e-afac-204baab6b1e8)  \n##### pom坐标形如:\n```\n  \u003cdependency\u003e\n      \u003cgroupId\u003ecom.lctking\u003c/groupId\u003e\n      \u003cartifactId\u003eBuZhouKit-Idempotent\u003c/artifactId\u003e\n      \u003cversion\u003e0.0.1-SNAPSHOT\u003c/version\u003e\n  \u003c/dependency\u003e\n```\n\n##### 方法二（推荐，将代码作为你的项目的一个模块来使用）  \n1，将代码克隆/下载到本地  \n2，将代码copy到项目某模块中  \n### 2，组件使用\n##### 简单概括：哪个方法需要满足幂等性，就将@Idempotent注解添加到该方法上，再根据业务特性来配置注解所需的参数。  \n##### 举个栗子(插入用户信息场景)：  \n```\n  @PostMapping(\"/redisCache-test\")\n  @Idempotent(\n          uniquePrefix = \"user:insert\",\n          spEL = \"#userDO.hashCode()\",\n          expireTime = -1L,\n          cacheType = CacheTypeEnum.REDIS,\n          message = \"添加用户请求重复,[BY_REDIS]\",\n          exceptionClass = CustomizeException.class\n  )\n  public void testIdempotentRelyOnDistributedCache(@RequestBody UserDO userDO){\n      userService.insertUser(userDO);\n  }\n```\n##### 加锁键 (即为下文中的key) 在真实redis中的形态如下图所示：\n![image](https://github.com/user-attachments/assets/b7e75752-e35f-4270-a53d-9c750790bbc7)  \n\n#### 2.1 核心参数的含义与使用建议：  \n##### 这里有必要先简单概述下该幂等注解的底层逻辑: 本质是通过缓存/数据库对键 (下文简称为key，在逻辑上key的构成: key = uniquePrefix + spEl.value) 加锁来实现幂等；  \n- uniquePrefix：锁前缀，用于表明该位置@Idempotent注解所修饰的方法有着什么样的业务特性。例如上例方法体逻辑为user信息的插入，那么uniquePrefix 设为 \"user:insert\" 是合适的；  \n\n- spEL：spel语句，实现动态定义加锁键。例如上例中\"#userDO.hashCode()\"即为key逻辑式中的spEl.value。[spEL语法学习-官方参考](https://docs.springframework.org.cn/spring-framework/reference/core/expressions.html)  \n\n- expireTime：顾名思义，是key的过期时间。建议根据业务特性来设置expireTime， 例如上例为添加用户场景，将键设置为永不过期来去重是合适的。如果是消息队列消费业务场景，设为10-30分钟是合适的；  \n\n- cacheType：缓存类型选择，按照缓存位置划分目前可分为两类，分别是：1，基于caffeine组件的本地缓存(对应枚举为 CacheTypeEnum.LOCAL 或 CacheTypeEnum.CAFFEINE)；2，基于redis的分布式缓存(CacheTypeEnum.REDIS)；  \n\n- message：幂等奏效抛出异常时的提示信息，建议根据业务场景来填写。  \n\n- exceptionClass：可由注解使用者自由设定的报错时抛出的异常类型，例如上例中的CustomizeException.class即为在测试项目中所配置的自定义异常类（该异常类不在幂等组件库中，可自由设定）。  \n\n### 3，功能测试\n#### 功能测试详见Test模块（与BuZhouKit-Idempotent模块并列）\n在application.yml中配置好你的本地redis服务后启动Test服务，进行功能测试：   \n路径：` http://127.0.0.1:8089/Idempotent-test/redisCache-test `  \n请求体[json] :  \n```\n  {\n    \"id\": 1,\n    \"username\": \"testUser0\",\n    \"password\": \"testPassworwd123\",\n    \"phone\": \"123-456-7890\"\n  }\n```\n#### 3.1 简单测试\n第一次请求，控制台打印：  \n![image](https://github.com/user-attachments/assets/3539277f-6e74-4e0b-b91b-620752238939)\n第二次请求，控制台打印（成功限流）：\n![image](https://github.com/user-attachments/assets/fe5d21b4-c667-4b0b-9926-f6064abe2edc)\n如图所示，不仅抛出了注解使用者自定义的异常类型，还附加了自定义的提示信息。\n#### 3.2 jmeter压测\n##### 条件：25个线程循环一百次；CSV数据文件设置包含一个含有20组json请求的txt文本。预计请求成功率0.8% (20/2500)\n##### 如图，符合预期，组件幂等性验证成功！\n![image](https://github.com/user-attachments/assets/9003c912-8823-47d7-8012-7b43b24b2fbf)\n\n\n\n\n\n### 4，tips\n- 如果你发现幂等注解在某些位置不奏效，请考虑AOP代理失效问题，如：同类内部的直接方法调用，这种调用不经过AOP代理对象，造成幂等注解失效。推荐的解决方法：将被调用方法抽取到合适的服务类接口及其实现类中。\n- ...\n\n### 5，TODO\n- 引入更详细的日志记录功能；  \n- 增加mysql相关功能支持；\n- ~~针对永久性幂等场景引入布隆过滤器~~ （已完成！）\n- ...\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flctking%2Fbuzhoukit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flctking%2Fbuzhoukit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flctking%2Fbuzhoukit/lists"}