From f8e57986747df0850f2567b5cf19e14d8da0035f Mon Sep 17 00:00:00 2001 From: yyaini112 <2505594512@qq.com> Date: 2020年12月12日 15:57:46 +0800 Subject: [PATCH 1/7] Merge pull request #177 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * :memo: 添加 MyBatisCodeHelper-Pro 鸣谢 * Merge branch 'dev' into master * Merge branch 'dev' into master * Merge branch 'dev' into master * Merge branch 'dev' into master * springboot nacos的demo,增加了pom依赖文件。 * SpringBoot整合nacos案例,增加了pom依赖文件。 --- demo-nacos/pom.xml | 57 +++++++++++++++++++ .../nacos/SpringBootDemoNacosApplication.java | 13 +++++ .../nacos/config/ConfigController.java | 26 +++++++++ .../nacos/discover/DiscoveryController.java | 29 ++++++++++ .../src/main/resources/application.properties | 1 + pom.xml | 2 + 6 files changed, 128 insertions(+) create mode 100644 demo-nacos/pom.xml create mode 100644 demo-nacos/src/main/java/com/xkcoding/nacos/SpringBootDemoNacosApplication.java create mode 100644 demo-nacos/src/main/java/com/xkcoding/nacos/config/ConfigController.java create mode 100644 demo-nacos/src/main/java/com/xkcoding/nacos/discover/DiscoveryController.java create mode 100644 demo-nacos/src/main/resources/application.properties diff --git a/demo-nacos/pom.xml b/demo-nacos/pom.xml new file mode 100644 index 000000000..4711ffaa0 --- /dev/null +++ b/demo-nacos/pom.xml @@ -0,0 +1,57 @@ + + + + spring-boot-demo + com.xkcoding + 1.0.0-SNAPSHOT + + 4.0.0 + + demo-nacos + + + + + com.alibaba.boot + nacos-discovery-spring-boot-starter + ${nacos.version} + + + + org.springframework.boot + spring-boot-starter-web + + + + com.alibaba.boot + nacos-config-spring-boot-starter + ${nacos.version} + + + + com.alibaba.boot + nacos-config-spring-boot-actuator + ${nacos.version} + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/demo-nacos/src/main/java/com/xkcoding/nacos/SpringBootDemoNacosApplication.java b/demo-nacos/src/main/java/com/xkcoding/nacos/SpringBootDemoNacosApplication.java new file mode 100644 index 000000000..36bb4e7c8 --- /dev/null +++ b/demo-nacos/src/main/java/com/xkcoding/nacos/SpringBootDemoNacosApplication.java @@ -0,0 +1,13 @@ +package com.xkcoding.nacos; + +import com.alibaba.nacos.spring.context.annotation.config.NacosPropertySource; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +@NacosPropertySource(dataId = "example", autoRefreshed = true) +public class SpringBootDemoNacosApplication { + public static void main(String[] args) { + SpringApplication.run(SpringBootDemoNacosApplication.class, args); + } +} diff --git a/demo-nacos/src/main/java/com/xkcoding/nacos/config/ConfigController.java b/demo-nacos/src/main/java/com/xkcoding/nacos/config/ConfigController.java new file mode 100644 index 000000000..40e862782 --- /dev/null +++ b/demo-nacos/src/main/java/com/xkcoding/nacos/config/ConfigController.java @@ -0,0 +1,26 @@ +package com.xkcoding.nacos.config; + +import com.alibaba.nacos.api.config.annotation.NacosValue; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import static org.springframework.web.bind.annotation.RequestMethod.GET; + +@Controller +@RequestMapping("config") +public class ConfigController { + @NacosValue(value = "${useLocalCache:false}", autoRefreshed = true) + private boolean useLocalCache; + + /** + * 1.通过nacos官网下载nacos服务,启动nacos服务。 + * 通过调用 Nacos Open API 向 Nacos server 发布配置:dataId 为example + * curl -X POST "http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=example&group=DEFAULT_GROUP&content=useLocalCache=true" + * @return + */ + @RequestMapping(value = "/get", method = GET) + @ResponseBody + public boolean get() { + return useLocalCache; + } +} diff --git a/demo-nacos/src/main/java/com/xkcoding/nacos/discover/DiscoveryController.java b/demo-nacos/src/main/java/com/xkcoding/nacos/discover/DiscoveryController.java new file mode 100644 index 000000000..3c2a506e3 --- /dev/null +++ b/demo-nacos/src/main/java/com/xkcoding/nacos/discover/DiscoveryController.java @@ -0,0 +1,29 @@ +package com.xkcoding.nacos.discover; + +import com.alibaba.nacos.api.annotation.NacosInjected; +import com.alibaba.nacos.api.exception.NacosException; +import com.alibaba.nacos.api.naming.NamingService; +import com.alibaba.nacos.api.naming.pojo.Instance; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; + +import java.util.List; + +import static org.springframework.web.bind.annotation.RequestMethod.GET; + +@Controller +@RequestMapping("discovery") +public class DiscoveryController { + + @NacosInjected + private NamingService namingService; + + @RequestMapping(value = "/get", method = GET) + @ResponseBody + public List get(@RequestParam String serviceName) throws NacosException { + return namingService.getAllInstances(serviceName); + } +} + diff --git a/demo-nacos/src/main/resources/application.properties b/demo-nacos/src/main/resources/application.properties new file mode 100644 index 000000000..e66b290d1 --- /dev/null +++ b/demo-nacos/src/main/resources/application.properties @@ -0,0 +1 @@ +nacos.config.server-addr=127.0.0.1:8848 diff --git a/pom.xml b/pom.xml index 0110e6452..e8cc2bdcc 100644 --- a/pom.xml +++ b/pom.xml @@ -70,6 +70,7 @@ demo-https demo-flyway demo-pay + demo-nacos pom @@ -87,6 +88,7 @@ 5.4.5 29.0-jre 1.20 + 0.2.4 From 5c3fb220a584a95f5ca663912dfc2cca5a87d7ec Mon Sep 17 00:00:00 2001 From: "Yangkai.Shen" <237497819@qq.com> Date: 2020年12月12日 16:48:31 +0800 Subject: [PATCH 2/7] =?UTF-8?q?:sparkles:=20=E5=AE=8C=E5=96=84=20PR=20?= =?UTF-8?q?=E7=9A=84=20nacos=20demo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- demo-nacos/pom.xml | 4 ++++ demo-nacos/src/main/resources/application.properties | 1 - demo-nacos/src/main/resources/application.yml | 9 +++++++++ pom.xml | 1 - 4 files changed, 13 insertions(+), 2 deletions(-) delete mode 100644 demo-nacos/src/main/resources/application.properties create mode 100644 demo-nacos/src/main/resources/application.yml diff --git a/demo-nacos/pom.xml b/demo-nacos/pom.xml index 4711ffaa0..41fe80c9a 100644 --- a/demo-nacos/pom.xml +++ b/demo-nacos/pom.xml @@ -11,6 +11,10 @@ demo-nacos + + 0.2.7 + + diff --git a/demo-nacos/src/main/resources/application.properties b/demo-nacos/src/main/resources/application.properties deleted file mode 100644 index e66b290d1..000000000 --- a/demo-nacos/src/main/resources/application.properties +++ /dev/null @@ -1 +0,0 @@ -nacos.config.server-addr=127.0.0.1:8848 diff --git a/demo-nacos/src/main/resources/application.yml b/demo-nacos/src/main/resources/application.yml new file mode 100644 index 000000000..a3704110d --- /dev/null +++ b/demo-nacos/src/main/resources/application.yml @@ -0,0 +1,9 @@ +nacos: + config: + server-addr: 127.0.0.1:8848 + discovery: + auto-register: true + server-addr: 127.0.0.1:8848 +spring: + application: + name: nacos-demo diff --git a/pom.xml b/pom.xml index e8cc2bdcc..702799f5b 100644 --- a/pom.xml +++ b/pom.xml @@ -88,7 +88,6 @@ 5.4.5 29.0-jre 1.20 - 0.2.4 From 0911bdfcbfa843473cca8b503331a297fc4e29b9 Mon Sep 17 00:00:00 2001 From: "yadong.zhang" Date: Wed, 6 Jan 2021 20:56:23 -0600 Subject: [PATCH 3/7] Merge pull request #182 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * :memo: 添加 MyBatisCodeHelper-Pro 鸣谢 * Merge branch 'dev' into master * Merge branch 'dev' into master * Merge branch 'dev' into master * Merge branch 'dev' into master * Update README --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 2d9b99a36..65c43b815 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ 3. 在 IDEA 中 Maven Projects 的面板导入项目根目录下 的 `pom.xml` 文件 4. Maven Projects 找不到的童鞋,可以勾上 IDEA 顶部工具栏的 View -> Tool Buttons ,然后 Maven Projects 的面板就会出现在 IDEA 的右侧 5. 找到各个 Module 的 Application 类就可以运行各个 demo 了 -6. **`注意:每个 demo 均有详细的 README 配套,食用 demo 前记得先看看哦~`** +6. **`注意:每个 demo 均有详细的 README 配套,使用 demo 前记得先看看哦~`** 7. **`注意:运行各个 demo 之前,有些是需要事先初始化数据库数据的,亲们别忘记了哦~`** ## 项目趋势 @@ -62,7 +62,7 @@ ### 开源推荐 -- `JustAuth`:史上最全的整合第三方登录的开源库,https://github.com/justauth/JustAuth +- `JustAuth`:开箱即用的整合第三方登录的开源组件,已集成国内外数十家平台,是实现第三方 OAuth 登录的不二之选。https://github.com/justauth/JustAuth - `Mica`:SpringBoot 微服务高效开发工具集,https://github.com/lets-mica/mica - `awesome-collector`:https://github.com/P-P-X/awesome-collector - `SpringBlade`:完整的线上解决方案(企业开发必备),https://github.com/chillzhuang/SpringBlade @@ -152,4 +152,4 @@ [MIT](http://opensource.org/licenses/MIT) -Copyright (c) 2018 Yangkai.Shen \ No newline at end of file +Copyright (c) 2018 Yangkai.Shen From d128c9a97003fe4a27b32dd24a57e6f477ef16da Mon Sep 17 00:00:00 2001 From: "Yangkai.Shen" <237497819@qq.com> Date: 2021年1月11日 14:22:39 +0800 Subject: [PATCH 4/7] =?UTF-8?q?:memo:=20=E6=9B=B4=E6=96=B0=20README.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.en.md | 4 ++-- README.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.en.md b/README.en.md index d3a479a5b..791840706 100644 --- a/README.en.md +++ b/README.en.md @@ -20,9 +20,9 @@ ## Introduction -`spring boot demo` is a project for learning and practicing `spring boot`, including `66` demos, and `55` of them have been done. +`spring boot demo` is a project for learning and practicing `Spring Boot`, the latest and most complete actual combat tutorial, including `66` demos, and `55` of them have been done. -This project has integrated actuator (`monitoring`), admin (`visual monitoring`), logback (`log`), aopLog (`recording web request logs through AOP`), global exception handling (`json level and page level` ), freemarker (`template engine`), thymeleaf (`template engine`), Beetl (`template engine`), Enjoy (`template engine`), JdbcTemplate (`general JDBC operate database`), JPA (`powerful ORM framework `), mybatis (`powerful ORM framework`), Generic Mapper (`mybatis quick operation `), PageHelper (`powerful mybatis pagination plugin`), mybatis-plus (`mybatis quick operation`), BeetlSQL (`powerful ORM framework `), upload (`local file upload and qiniu cloud file upload`), redis (`cache`), ehcache (`cache`), email (`send various types of mail`), task (`basic scheduled tasks`), quartz (`dynamic management scheduled tasks`), xxl-job (`distributed scheduled tasks`), swagger (`API interface management and tests`), security (`RBAC-based Dynamic Rights Authentication`), SpringSession (`session sharing`), Zookeeper (`implement distributed locks by AOP`), RabbitMQ (`message queue`), Kafka (`message queue`), websocket (` server pushes the monitoring server status to front end `), socket.io (`chat room`), ureport2 (`Chinese-style report`), packaged into a `war` file, integrate ElasticSearch (`basic operations and advanced queries`), Async ( `asynchronous tasks`), integrated Dubbo (`with official starter`), MongoDB (`document database`), neo4j (`graph database`), docker (`container`), `JPA Multi-Datasource`, `Mybatis Multi-Datasource`, `code generator`', GrayLog (`log collection`), JustAuth (`third-party login`), LDAP(`CURD`), `Dynamically add/switch datasources`, Standalone RateLimiting(`AOP + Guava RateLimiter`), Distributed Ratelimiting(`AOP + Redis + Lua`), ElasticSearch 7.x(`use official Rest High Level Client`), HTTPS, Flyway(`initialize databases`),UReport2(`Chinese complex report `). +It covers the template engine, ORM framework, distributed technology, authorization and authentication and other enterprise-level practical solutions, and the specific modules included are shown in the following [table](#Introduction of each Module). > If you have demos to contribute or needs to meet, it is very welcome to submit a [issue](https://github.com/xkcoding/spring-boot-demo/issues/new) and I will add it to my [TODO](./TODO.en.md) list. diff --git a/README.md b/README.md index 65c43b815..cd2d27884 100644 --- a/README.md +++ b/README.md @@ -20,9 +20,9 @@ ## 项目简介 -`spring boot demo` 是一个用来深度学习并实战 `spring boot` 的项目,目前总共包含 **`66`** 个集成demo,已经完成 **`55`** 个。 +`spring boot demo` 是一个用来深入学习并实战 `Spring Boot` 的项目,是目前全网、最新最全的实战教程,总共包含 **`66`** 个集成demo,已经完成 **`55`** 个。 -该项目已成功集成 actuator(`监控`)、admin(`可视化监控`)、logback(`日志`)、aopLog(`通过AOP记录web请求日志`)、统一异常处理(`json级别和页面级别`)、freemarker(`模板引擎`)、thymeleaf(`模板引擎`)、Beetl(`模板引擎`)、Enjoy(`模板引擎`)、JdbcTemplate(`通用JDBC操作数据库`)、JPA(`强大的ORM框架`)、mybatis(`强大的ORM框架`)、通用Mapper(`快速操作Mybatis`)、PageHelper(`通用的Mybatis分页插件`)、mybatis-plus(`快速操作Mybatis`)、BeetlSQL(`强大的ORM框架`)、upload(`本地文件上传和七牛云文件上传`)、redis(`缓存`)、ehcache(`缓存`)、email(`发送各种类型邮件`)、task(`基础定时任务`)、quartz(`动态管理定时任务`)、xxl-job(`分布式定时任务`)、swagger(`API接口管理测试`)、security(`基于RBAC的动态权限认证`)、SpringSession(`Session共享`)、Zookeeper(`结合AOP实现分布式锁`)、RabbitMQ(`消息队列`)、Kafka(`消息队列`)、websocket(`服务端推送监控服务器运行信息`)、socket.io(`聊天室`)、ureport2(`中国式报表`)、打包成`war`文件、集成 ElasticSearch(`基本操作和高级查询`)、Async(`异步任务`)、集成Dubbo(`采用官方的starter`)、MongoDB(`文档数据库`)、neo4j(`图数据库`)、docker(`容器化`)、`JPA多数据源`、`Mybatis多数据源`、`代码生成器`、GrayLog(`日志收集`)、JustAuth(`第三方登录`)、LDAP(`增删改查`)、`动态添加/切换数据源`、单机限流(`AOP + Guava RateLimiter`)、分布式限流(`AOP + Redis + Lua`)、ElasticSearch 7.x(`使用官方 Rest High Level Client`)、HTTPS、Flyway(`数据库初始化`)、UReport2(`中国式复杂报表`)。 +涵盖模板引擎、ORM框架、分布式技术、授权认证等企业级实战方案,具体包括的模块参见下方[表格](#各-module-介绍)。 > 如果大家还有想要集成的demo,也可在 [issue](https://github.com/xkcoding/spring-boot-demo/issues/new) 里提需求。我会额外添加在 [TODO](./TODO.md) 列表里。✊ From 00ab9b335075d05459121341596bb594f48eb6c8 Mon Sep 17 00:00:00 2001 From: "Yangkai.Shen" <237497819@qq.com> Date: 2021年1月11日 14:24:39 +0800 Subject: [PATCH 5/7] =?UTF-8?q?:memo:=20=E6=9B=B4=E6=96=B0=20README.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.en.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.en.md b/README.en.md index 791840706..3ed81a33a 100644 --- a/README.en.md +++ b/README.en.md @@ -22,7 +22,7 @@ `spring boot demo` is a project for learning and practicing `Spring Boot`, the latest and most complete actual combat tutorial, including `66` demos, and `55` of them have been done. -It covers the template engine, ORM framework, distributed technology, authorization and authentication and other enterprise-level practical solutions, and the specific modules included are shown in the following [table](#Introduction of each Module). +It covers the template engine, ORM framework, distributed technology, authorization and authentication and other enterprise-level practical solutions, and the specific modules included are shown in the following [table](#introduction-of-each-module). > If you have demos to contribute or needs to meet, it is very welcome to submit a [issue](https://github.com/xkcoding/spring-boot-demo/issues/new) and I will add it to my [TODO](./TODO.en.md) list. From edbdf4d7c1a6734b774a0b770cd4d018601af3e8 Mon Sep 17 00:00:00 2001 From: "Yangkai.Shen" <237497819@qq.com> Date: 2021年1月27日 20:11:41 +0800 Subject: [PATCH 6/7] =?UTF-8?q?:memo:=20=E6=9B=B4=E6=96=B0=20README.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.en.md | 3 +-- README.md | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/README.en.md b/README.en.md index 3ed81a33a..fd1fcd422 100644 --- a/README.en.md +++ b/README.en.md @@ -110,7 +110,7 @@ View the [TODO](./TODO.en.md) file | [demo-mq-kafka](./demo-mq-kafka) | a demo to integrate Kafka implementation for message delivery and reception. | | [demo-websocket](./demo-websocket) | a demo to integrate websocket, the backend actively pushes the server running status to front end. | | [demo-websocket-socketio](./demo-websocket-socketio) | a demo to integrate websocket by using `netty-socketio`, implement a simple chat room. | -| [demo-ureport2](./demo-ureport2) | NOT FINISHED YET! a demo to integrate [ureport2](https://github.com/youseries/ureport) to implement complex, customized Chinese-style reports. | +| [demo-ureport2](./demo-ureport2) | a demo to integrate [ureport2](https://github.com/youseries/ureport) to implement complex, customized Chinese-style reports. | | [demo-uflo](./demo-uflo) | NOT FINISHED YET! a demo to integrate [uflo](https://github.com/youseries/uflo)(process engine like Activiti and Flowable) to quickly implement a lightweight process engine. | | [demo-urule](./demo-urule) | NOT FINISHED YET! a demo to integrate [urule](https://github.com/youseries/urule)(rule engine like drools) fast implementation rule engine. | | [demo-activiti](./demo-activiti) | NOT FINISHED YET! a demo to integrate Activiti 7 process engine. | @@ -136,7 +136,6 @@ View the [TODO](./TODO.en.md) file | [demo-https](./demo-https) | a demo to integrate HTTPS. | | [demo-elasticsearch-rest-high-level-client](./demo-elasticsearch-rest-high-level-client) | a demo to integrate ElasticSearch 7.x version by using official Rest High Level Client to operate ES data. | | [demo-flyway](./demo-flyway) | a demo to integrate Flyway to initialize tables and data in database, Flyway also support the sql script version control. | -| [demo-ureport2](./demo-ureport2) | a demo to integrate Ureport2 to design the Chinese complex report file. | ### Thanks diff --git a/README.md b/README.md index cd2d27884..73702698e 100644 --- a/README.md +++ b/README.md @@ -114,7 +114,7 @@ | [demo-mq-kafka](./demo-mq-kafka) | spring-boot 集成 kafka,实现消息的发送和接收 | | [demo-websocket](./demo-websocket) | spring-boot 集成 websocket,后端主动推送前端服务器运行信息 | | [demo-websocket-socketio](./demo-websocket-socketio) | spring-boot 使用 netty-socketio 集成 websocket,实现一个简单的聊天室 | -| [demo-ureport2](./demo-ureport2) | spring-boot 集成 ureport2 实现复杂的自定义的中国式报表 待完成 | +| [demo-ureport2](./demo-ureport2) | spring-boot 集成 ureport2 实现复杂的自定义的中国式报表 | | [demo-uflo](./demo-uflo) | spring-boot 集成 uflo 快速实现轻量级流程引擎 待完成 | | [demo-urule](./demo-urule) | spring-boot 集成 urule 快速实现规则引擎 待完成 | | [demo-activiti](./demo-activiti) | spring-boot 集成 activiti 7 流程引擎 待完成 | @@ -140,7 +140,7 @@ | [demo-https](./demo-https) | spring-boot 集成 HTTPS | | [demo-elasticsearch-rest-high-level-client](./demo-elasticsearch-rest-high-level-client) | spring boot 集成 ElasticSearch 7.x 版本,使用官方 Rest High Level Client 操作 ES 数据 | | [demo-flyway](./demo-flyway) | spring boot 集成 Flyway,项目启动时初始化数据库表结构,同时支持数据库脚本版本控制 | -| [demo-ureport2](./demo-ureport2) | spring boot 集成 Ureport2,实现中国式复杂报表设计 | + ### 感谢 From e15fd4aedde14b1401a9ca156a333f77ffb41722 Mon Sep 17 00:00:00 2001 From: "Yangkai.Shen" <237497819@qq.com> Date: 2021年4月10日 16:56:48 +0800 Subject: [PATCH 7/7] :sparkles: add zookeeper cluster demo --- demo-zookeeper/README.md | 2 +- .../docs/cluster/docker-compose.yml | 29 ++++++++++++++ .../docs/standalone/docker-compose.yml | 8 ++++ demo-zookeeper/pom.xml | 2 +- .../xkcoding/zookeeper/config/ZkConfig.java | 4 +- .../src/main/resources/application.yml | 3 +- ...ringBootDemoZookeeperApplicationTests.java | 38 ++++++++++++++----- 7 files changed, 72 insertions(+), 14 deletions(-) create mode 100644 demo-zookeeper/docs/cluster/docker-compose.yml create mode 100644 demo-zookeeper/docs/standalone/docker-compose.yml diff --git a/demo-zookeeper/README.md b/demo-zookeeper/README.md index 15d10b9dd..72a61edae 100644 --- a/demo-zookeeper/README.md +++ b/demo-zookeeper/README.md @@ -433,4 +433,4 @@ public class SpringBootDemoZookeeperApplicationTests { ## 参考 1. [如何在测试类中使用 AOP](https://stackoverflow.com/questions/11436600/unit-testing-spring-around-aop-methods) -2. zookeeper 实现分布式锁:《Spring Boot 2精髓 从构建小系统到架构分布式大系统》李家智 - 第16章 - Spring Boot 和 Zoo Keeper - 16.3 实现分布式锁 +2. zookeeper 实现分布式锁:《Spring Boot 2精髓 从构建小系统到架构分布式大系统》李家智 - 第16章 - Spring Boot 和 ZooKeeper - 16.3 实现分布式锁 diff --git a/demo-zookeeper/docs/cluster/docker-compose.yml b/demo-zookeeper/docs/cluster/docker-compose.yml new file mode 100644 index 000000000..a1fbfc604 --- /dev/null +++ b/demo-zookeeper/docs/cluster/docker-compose.yml @@ -0,0 +1,29 @@ +version: '3.8' + +services: + zoo1: + image: zookeeper:3.7.0 + hostname: zoo1 + ports: + - 2181:2181 + environment: + ZOO_MY_ID: 1 + ZOO_SERVERS: server.1=0.0.0.0:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=zoo3:2888:3888;2181 + + zoo2: + image: zookeeper:3.7.0 + hostname: zoo2 + ports: + - 2182:2181 + environment: + ZOO_MY_ID: 2 + ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=0.0.0.0:2888:3888;2181 server.3=zoo3:2888:3888;2181 + + zoo3: + image: zookeeper:3.7.0 + hostname: zoo3 + ports: + - 2183:2181 + environment: + ZOO_MY_ID: 3 + ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=0.0.0.0:2888:3888;2181 diff --git a/demo-zookeeper/docs/standalone/docker-compose.yml b/demo-zookeeper/docs/standalone/docker-compose.yml new file mode 100644 index 000000000..c796b46bd --- /dev/null +++ b/demo-zookeeper/docs/standalone/docker-compose.yml @@ -0,0 +1,8 @@ +version: '3.8' + +services: + zoo1: + image: zookeeper:3.7.0 + hostname: zoo1 + ports: + - 2181:2181 diff --git a/demo-zookeeper/pom.xml b/demo-zookeeper/pom.xml index a22a8cb16..f3402a297 100644 --- a/demo-zookeeper/pom.xml +++ b/demo-zookeeper/pom.xml @@ -44,7 +44,7 @@ org.apache.curator curator-recipes - 4.1.0 + 5.1.0 diff --git a/demo-zookeeper/src/main/java/com/xkcoding/zookeeper/config/ZkConfig.java b/demo-zookeeper/src/main/java/com/xkcoding/zookeeper/config/ZkConfig.java index 3c25c69e9..ca8b085aa 100644 --- a/demo-zookeeper/src/main/java/com/xkcoding/zookeeper/config/ZkConfig.java +++ b/demo-zookeeper/src/main/java/com/xkcoding/zookeeper/config/ZkConfig.java @@ -1,6 +1,7 @@ package com.xkcoding.zookeeper.config; import com.xkcoding.zookeeper.config.props.ZkProps; +import lombok.extern.slf4j.Slf4j; import org.apache.curator.RetryPolicy; import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.CuratorFrameworkFactory; @@ -18,6 +19,7 @@ * @author yangkai.shen * @date Created in 2018年12月27日 14:45 */ +@Slf4j @Configuration @EnableConfigurationProperties(ZkProps.class) public class ZkConfig { @@ -28,7 +30,7 @@ public ZkConfig(ZkProps zkProps) { this.zkProps = zkProps; } - @Bean + @Bean(destroyMethod = "close") public CuratorFramework curatorFramework() { RetryPolicy retryPolicy = new ExponentialBackoffRetry(zkProps.getTimeout(), zkProps.getRetry()); CuratorFramework client = CuratorFrameworkFactory.newClient(zkProps.getUrl(), retryPolicy); diff --git a/demo-zookeeper/src/main/resources/application.yml b/demo-zookeeper/src/main/resources/application.yml index 2a79b2119..308c3d917 100644 --- a/demo-zookeeper/src/main/resources/application.yml +++ b/demo-zookeeper/src/main/resources/application.yml @@ -4,6 +4,7 @@ server: context-path: /demo zk: - url: 127.0.0.1:2181 + url: zoo1:2181 +# url: zoo1:2181,zoo2:2182,zoo3:2183 timeout: 1000 retry: 3 diff --git a/demo-zookeeper/src/test/java/com/xkcoding/zookeeper/SpringBootDemoZookeeperApplicationTests.java b/demo-zookeeper/src/test/java/com/xkcoding/zookeeper/SpringBootDemoZookeeperApplicationTests.java index a2b30d7fa..beaf25af9 100644 --- a/demo-zookeeper/src/test/java/com/xkcoding/zookeeper/SpringBootDemoZookeeperApplicationTests.java +++ b/demo-zookeeper/src/test/java/com/xkcoding/zookeeper/SpringBootDemoZookeeperApplicationTests.java @@ -4,6 +4,7 @@ import com.xkcoding.zookeeper.aspectj.ZooLockAspect; import lombok.extern.slf4j.Slf4j; import org.apache.curator.framework.CuratorFramework; +import org.apache.curator.framework.imps.CuratorFrameworkState; import org.apache.curator.framework.recipes.locks.InterProcessMutex; import org.junit.Test; import org.junit.runner.RunWith; @@ -12,6 +13,7 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; +import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; @@ -32,6 +34,12 @@ public Integer getCount() { @Autowired private CuratorFramework zkClient; + @Test + public void testZkClient() { + CuratorFrameworkState state = zkClient.getState(); + log.info(state.name()); + } + /** * 不使用分布式锁,程序结束查看count的值是否为0 */ @@ -53,9 +61,11 @@ public void testAopLock() throws InterruptedException { ZooLockAspect aspect = new ZooLockAspect(zkClient); factory.addAspect(aspect); SpringBootDemoZookeeperApplicationTests proxy = factory.getProxy(); - IntStream.range(0, 10000).forEach(i -> executorService.execute(() -> proxy.aopBuy(i))); - TimeUnit.MINUTES.sleep(1); - log.error("count值为{}", proxy.getCount()); + int total = 10000; + CountDownLatch latch = new CountDownLatch(total); + IntStream.range(0, total).forEach(i -> executorService.execute(() -> proxy.aopBuy(i, latch))); + latch.await(); + log.error("count最终剩余值为{}", proxy.getCount()); } /** @@ -63,19 +73,22 @@ public void testAopLock() throws InterruptedException { */ @Test public void testManualLock() throws InterruptedException { - IntStream.range(0, 10000).forEach(i -> executorService.execute(this::manualBuy)); - TimeUnit.MINUTES.sleep(1); - log.error("count值为{}", count); + int total = 10000; + CountDownLatch latch = new CountDownLatch(total); + IntStream.range(0, total).forEach(i -> executorService.execute(() -> manualBuy(latch))); + latch.await(); + log.error("count最终剩余值为{}", count); } @ZooLock(key = "buy", timeout = 1, timeUnit = TimeUnit.MINUTES) - public void aopBuy(int userId) { + public void aopBuy(int userId, CountDownLatch latch) { log.info("{} 正在出库。。。", userId); doBuy(); log.info("{} 扣库存成功。。。", userId); + latch.countDown(); } - public void manualBuy() { + public void manualBuy(CountDownLatch latch) { String lockPath = "/buy"; log.info("try to buy sth."); try { @@ -84,12 +97,17 @@ public void manualBuy() { if (lock.acquire(1, TimeUnit.MINUTES)) { doBuy(); log.info("buy successfully!"); + } else { + log.info("buy failed...."); } } finally { - lock.release(); + if (lock.isOwnedByCurrentThread()) { + lock.release(); + } + latch.countDown(); } } catch (Exception e) { - log.error("zk error"); + log.error("zk error", e); } } AltStyle によって変換されたページ (->オリジナル) / アドレス: モード: デフォルト 音声ブラウザ ルビ付き 配色反転 文字拡大 モバイル
AltStyle によって変換されたページ (->オリジナル) / アドレス: モード: デフォルト 音声ブラウザ ルビ付き 配色反転 文字拡大 モバイル