作者:じ☆ve不哭
> 在pycharm中完美运行的代码在部署到服务器后为什么会出现ModuleNotFoundError:no model named *呢? #### 原因 因为工作路径的问题。当你在pycharm运行程序的时候,pycharm默认将你当前的文件夹作为了工作路径,那么你 import 你的模块也就顺理成章了,但是在终端就不一样了哦。原因是…(PYTHONPATH, 等) #### 解决 ##### 方法一 在你的主程序,也就是你想要在终端运行但是报错的程序中加入工作路径就好了: ``` import os import sys sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../../') # 就是将你上层的文件夹添加到工作路径,当然包括文件夹下。 # 注意这三行要放到你要导入的模块的前面 ``` ##### 方法二 配置环境变量PYTHONPATH 默认我们import的模块都会从PYTHONPATH里面寻找。
作者:微信小助手
<p style="white-space: normal;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);text-align: center;" data-mpa-powered-by="yiban.io"><span style="letter-spacing: 0.544px;widows: 1;word-spacing: 2px;caret-color: rgb(51, 51, 51);font-family: Optima-Regular, PingFangTC-light;color: rgb(127, 127, 127);font-size: 14px;line-height: 1.75em;"></span></p> <p style="margin-bottom: 10px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;color: rgb(62, 62, 62);font-size: 15px;background-color: rgb(255, 255, 255);line-height: normal;text-align: center;"><span style="font-size: 14px;letter-spacing: 0.544px;word-spacing: 2px;color: rgb(136, 136, 136);">点击蓝色“</span><span style="font-size: 14px;letter-spacing: 0.544px;word-spacing: 2px;color: rgb(0, 128, 255);">架构文摘</span><span style="font-size: 14px;letter-spacing: 0.544px;word-spacing: 2px;color: rgb(136, 136, 136);">”关注我哟</span></p> <p style="margin-bottom: 10px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;color: rgb(62, 62, 62);font-size: 15px;background-color: rgb(255, 255, 255);text-size-adjust: auto;word-spacing: 2px;text-align: center;"><span style="font-size: 14px;color: rgb(136, 136, 136);">加个“</span><span style="color: rgb(0, 128, 255);font-size: 14px;">星标</span><span style="font-size: 14px;color: rgb(136, 136, 136);">”,每天上午 09:25,干货推送!</span></p> <p style="font-family: -apple-system-font, system-ui, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;color: rgb(62, 62, 62);font-size: 14px;background-color: rgb(255, 255, 255);text-align: center;"><img data-backh="36" data-backw="578" data-ratio="0.0625" data-s="300,640" data-type="jpeg" data-w="640" width="100%" src="/upload/8c292e55ba5a23cb6ebc11f2a2c4fece.jpg" style="font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;widows: 1;word-spacing: 2px;color: rgb(136, 136, 136);box-sizing: border-box !important;visibility: visible !important;width: 677px !important;"></p> <section> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"><em><span style="font-size: 12px;text-align: right;">作者:Jedrzejewski</span></em></span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);"><em><span style="color: rgb(136, 136, 136);font-size: 12px;text-align: right;">来源:e4developer.com/2018/08/06/</span></em></span></p> </section> <p><br></p> <hr style="border-style: solid;border-width: 1px 0px 0px;border-color: rgba(0, 0, 0, 0.1);transform-origin: 0px 0px;transform: scale(1, 0.5);"> <p><span style="font-size: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;text-align: start;">Spring Boot 是最流行的用于开发微服务的 Java 框架。在本文中,我将与你分享自 2016 年以来我在专业开发中使用 Spring Boot 所采用的最佳实践。这些内容是基于我的个人经验和一些熟知的 Spring Boot 专家的文章。<br></span></p> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><span style="font-size: 15px;">在本文中,我将重点介绍 Spring Boot 特有的实践(大多数时候,也适用于 Spring 项目)。以下依次列出了最佳实践,排名不分先后。</span></p> <h3 style="box-sizing: border-box;margin-top: 2rem;margin-bottom: 0.5rem;font-weight: 700;color: rgb(255, 140, 0);line-height: 1.35;font-size: 18px;text-align: start;white-space: normal;font-family: Menlo, Monaco, 'Source Code Pro', Consolas, Inconsolata, 'Ubuntu Mono', 'DejaVu Sans Mono', 'Courier New', 'Droid Sans Mono', 'Hiragino Sans GB', 微软雅黑, monospace !important;"><span style="font-size: 15px;color: rgb(123, 12, 0);">1、使用自定义 BOM 来维护第三方依赖</span></h3> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><span style="font-size: 15px;">这条实践是我根据实际项目中的经历总结出的。</span></p> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><span style="font-size: 15px;">Spring Boot 项目本身使用和集成了大量的开源项目,它帮助我们维护了这些第三方依赖。但是也有一部分在实际项目使用中并没有包括进来,这就需要我们在项目中自己维护版本。如果在一个大型的项目中,包括了很多未开发模块,那么维护起来就非常的繁琐。</span></p> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><span style="font-size: 15px;">怎么办呢?事实上,Spring IO Platform 就是做的这个事情,它本身就是 Spring Boot 的子项目,同时维护了其他第三方开源库。我们可以借鉴 Spring IO Platform 来编写自己的基础项目 platform-bom,所有的业务模块项目应该以 BOM 的方式引入。这样在升级第三方依赖时,就只需要升级这一个依赖的版本而已。</span></p> <pre style="box-sizing: border-box;padding: 0.5em;font-family: Courier, 'Courier New', monospace;background: rgb(45, 45, 45);border-width: 1px;border-style: solid;border-color: rgb(221, 221, 221);overflow-x: auto;color: rgb(204, 204, 204);font-size: 15px;text-align: start;"><code style=""><span style="font-size: 15px;"><dependencyManagement><br> <dependencies><br> <dependency><br> <groupId>io.spring.platform</groupId><br> <artifactId>platform-bom</artifactId><br> <version>Cairo-SR3</version><br> <type>pom</type><br> <scope><span style="box-sizing: border-box;font-weight: 700;color: rgb(204, 153, 204);">import</span></scope><br> </dependency><br> </dependencies><br></dependencyManagement><br></span></code></pre> <h3 style="box-sizing: border-box;margin-top: 2rem;margin-bottom: 0.5rem;font-weight: 700;color: rgb(255, 140, 0);line-height: 1.35;font-size: 18px;text-align: start;white-space: normal;font-family: Menlo, Monaco, 'Source Code Pro', Consolas, Inconsolata, 'Ubuntu Mono', 'DejaVu Sans Mono', 'Courier New', 'Droid Sans Mono', 'Hiragino Sans GB', 微软雅黑, monospace !important;"><span style="font-size: 15px;color: rgb(123, 12, 0);">2、使用自动配置</span></h3> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><span style="font-size: 15px;">Spring Boot 的一个主要特性是使用自动配置。这是 Spring Boot 的一部分,它可以简化你的代码并使之工作。当在类路径上检测到特定的 jar 文件时,自动配置就会被激活。</span></p> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><span style="font-size: 15px;">使用它的最简单方法是依赖 Spring Boot Starters。因此,如果你想与 Redis 进行集成,你可以首先包括:</span></p> <pre style="box-sizing: border-box;padding: 0.5em;font-family: Courier, 'Courier New', monospace;background: rgb(45, 45, 45);border-width: 1px;border-style: solid;border-color: rgb(221, 221, 221);overflow-x: auto;color: rgb(204, 204, 204);font-size: 15px;text-align: start;"><code style=""><span style="font-size: 15px;"><dependency><br> <groupId>org.springframework.boot</groupId><br> <artifactId>spring-boot-starter-data-redis</artifactId><br></dependency><br></span></code></pre> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><span style="font-size: 15px;">如果你想与 MongoDB 进行集成,需要这样:</span></p> <pre style="box-sizing: border-box;padding: 0.5em;font-family: Courier, 'Courier New', monospace;background: rgb(45, 45, 45);border-width: 1px;border-style: solid;border-color: rgb(221, 221, 221);overflow-x: auto;color: rgb(204, 204, 204);font-size: 15px;text-align: start;"><code style=""><span style="font-size: 15px;"><dependency><br> <groupId>org.springframework.boot</groupId><br> <artifactId>spring-boot-starter-data-mongodb</artifactId><br></dependency><br></span></code></pre> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><span style="font-size: 15px;">借助于这些 starters,这些繁琐的配置就可以很好地集成起来并协同工作,而且它们都是经过测试和验证的。这非常有助于避免可怕的 Jar 地狱。</span></p> <blockquote style="box-sizing: border-box;margin-bottom: 1.2em;padding: 15px 15px 15px 1rem;color: rgb(129, 145, 152);border-left-width: 6px;border-left-color: rgb(96, 125, 139);font-size: 14px;line-height: 18px;background: rgb(242, 247, 251);font-family: Helvetica, Arial, sans-serif;text-align: start;white-space: normal;"> <p style="box-sizing: border-box;"><span style="font-size: 15px;">https://dzone.com/articles/what-is-jar-hell</span></p> </blockquote> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><span style="font-size: 15px;">通过使用以下注解属性,可以从自动配置中排除某些配置类:</span></p> <pre style="box-sizing: border-box;padding: 0.5em;font-family: Courier, 'Courier New', monospace;background: rgb(45, 45, 45);border-width: 1px;border-style: solid;border-color: rgb(221, 221, 221);overflow-x: auto;color: rgb(204, 204, 204);font-size: 15px;text-align: start;"><code style=""><span style="font-size: 15px;"><span style="box-sizing: border-box;color: rgb(249, 145, 87);">@EnableAutoConfiguration</span>(exclude = {ClassNotToAutoconfigure.class})<br></span></code></pre> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><span style="font-size: 15px;">但只有在绝对必要时才应该这样做。</span></p> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><span style="font-size: 15px;">有关自动配置的官方文档可在此处找到:</span></p> <blockquote style="box-sizing: border-box;margin-bottom: 1.2em;padding: 15px 15px 15px 1rem;color: rgb(129, 145, 152);border-left-width: 6px;border-left-color: rgb(96, 125, 139);font-size: 14px;line-height: 18px;background: rgb(242, 247, 251);font-family: Helvetica, Arial, sans-serif;text-align: start;white-space: normal;"> <p style="box-sizing: border-box;"><span style="font-size: 15px;">https://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-auto-configuration.html。</span></p> </blockquote> <h3 style="box-sizing: border-box;margin-top: 2rem;margin-bottom: 0.5rem;font-weight: 700;color: rgb(255, 140, 0);line-height: 1.35;font-size: 18px;text-align: start;white-space: normal;font-family: Menlo, Monaco, 'Source Code Pro', Consolas, Inconsolata, 'Ubuntu Mono', 'DejaVu Sans Mono', 'Courier New', 'Droid Sans Mono', 'Hiragino Sans GB', 微软雅黑, monospace !important;"><span style="font-size: 15px;color: rgb(123, 12, 0);">3、使用 Spring Initializr 来开始一个新的 Spring Boot 项目</span></h3> <blockquote style="box-sizing: border-box;margin-bottom: 1.2em;padding: 15px 15px 15px 1rem;color: rgb(129, 145, 152);border-left-width: 6px;border-left-color: rgb(96, 125, 139);font-size: 14px;line-height: 18px;background: rgb(242, 247, 251);font-family: Helvetica, Arial, sans-serif;text-align: start;white-space: normal;"> <p style="box-sizing: border-box;"><span style="font-size: 15px;">这一条最佳实践来自 Josh Long (Spring Advocate,@starbuxman)。</span></p> </blockquote> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><span style="font-size: 15px;">Spring Initializr 提供了一个超级简单的方法来创建一个新的 Spring Boot 项目,并根据你的需要来加载可能使用到的依赖。</span></p> <blockquote style="box-sizing: border-box;margin-bottom: 1.2em;padding: 15px 15px 15px 1rem;color: rgb(129, 145, 152);border-left-width: 6px;border-left-color: rgb(96, 125, 139);font-size: 14px;line-height: 18px;background: rgb(242, 247, 251);font-family: Helvetica, Arial, sans-serif;text-align: start;white-space: normal;"> <p style="box-sizing: border-box;"><span style="font-size: 15px;">https://start.spring.io/</span></p> </blockquote> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><span style="font-size: 15px;">使用 Initializr 创建应用程序可确保你获得经过测试和验证的依赖项,这些依赖项适用于 Spring 自动配置。你甚至可能会发现一些新的集成,但你可能并没有意识到这些。</span></p> <h3 style="box-sizing: border-box;margin-top: 2rem;margin-bottom: 0.5rem;font-weight: 700;color: rgb(255, 140, 0);line-height: 1.35;font-size: 18px;text-align: start;white-space: normal;font-family: Menlo, Monaco, 'Source Code Pro', Consolas, Inconsolata, 'Ubuntu Mono', 'DejaVu Sans Mono', 'Courier New', 'Droid Sans Mono', 'Hiragino Sans GB', 微软雅黑, monospace !important;"><span style="font-size: 15px;color: rgb(123, 12, 0);">4、考虑为常见的组织问题创建自己的自动配置</span></h3> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><span style="font-size: 15px;">这一条也来自 Josh Long(Spring Advocate,@starbuxman)——这个实践是针对高级用户的。</span></p> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><span style="font-size: 15px;">如果你在一个严重依赖 Spring Boot 的公司或团队中工作,并且有共同的问题需要解决,那么你可以创建自己的自动配置。</span></p> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><span style="font-size: 15px;">这项任务涉及较多工作,因此你需要考虑何时获益是值得投入的。与多个略有不同的定制配置相比,维护单个自动配置更容易。</span></p> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><span style="font-size: 15px;">如果将这个提供 Spring Boot 配置以开源库的形式发布出去,那么将极大地简化数千个用户的配置工作。</span></p> <h3 style="box-sizing: border-box;margin-top: 2rem;margin-bottom: 0.5rem;font-weight: 700;color: rgb(255, 140, 0);line-height: 1.35;font-size: 18px;text-align: start;white-space: normal;font-family: Menlo, Monaco, 'Source Code Pro', Consolas, Inconsolata, 'Ubuntu Mono', 'DejaVu Sans Mono', 'Courier New', 'Droid Sans Mono', 'Hiragino Sans GB', 微软雅黑, monospace !important;"><span style="font-size: 15px;color: rgb(123, 12, 0);">5、正确设计代码目录结构</span></h3> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><span style="font-size: 15px;">尽管允许你有很大的自由,但是有一些基本规则值得遵守来设计你的源代码结构。</span></p> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><span style="font-size: 15px;">避免使用默认包。确保所有内容(包括你的入口点)都位于一个名称很好的包中,这样就可以避免与装配和组件扫描相关的意外情况;</span></p> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><span style="font-size: 15px;">将 Application.java(应用的入口类)保留在顶级源代码目录中;</span></p> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><span style="font-size: 15px;">我建议将控制器和服务放在以功能为导向的模块中,但这是可选的。一些非常好的开发人员建议将所有控制器放在一起。不论怎样,坚持一种风格!</span></p> <h3 style="box-sizing: border-box;margin-top: 2rem;margin-bottom: 0.5rem;font-weight: 700;color: rgb(255, 140, 0);line-height: 1.35;font-size: 18px;text-align: start;white-space: normal;font-family: Menlo, Monaco, 'Source Code Pro', Consolas, Inconsolata, 'Ubuntu Mono', 'DejaVu Sans Mono', 'Courier New', 'Droid Sans Mono', 'Hiragino Sans GB', 微软雅黑, monospace !important;"><span style="font-size: 15px;color: rgb(123, 12, 0);">6、保持 @Controller 的简洁和专注</span></h3> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><span style="font-size: 15px;">Controller 应该非常简单。你可以在此处阅读有关 GRASP 中有关控制器模式部分的说明。你希望控制器作为协调和委派的角色,而不是执行实际的业务逻辑。以下是主要做法:</span></p> <blockquote style="box-sizing: border-box;margin-bottom: 1.2em;padding: 15px 15px 15px 1rem;color: rgb(129, 145, 152);border-left-width: 6px;border-left-color: rgb(96, 125, 139);font-size: 14px;line-height: 18px;background: rgb(242, 247, 251);font-family: Helvetica, Arial, sans-serif;text-align: start;white-space: normal;"> <p style="box-sizing: border-box;"><span style="font-size: 15px;">https://en.wikipedia.org/wiki/GRASP_(object-oriented_design)#Controller</span></p> </blockquote> <ul style="padding-left: 20px;list-style: square;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;margin-top: 2px !important;" class="list-paddingleft-2"> <li style="box-sizing: border-box;margin-top: 2px !important;font-size: 15px;"><p style="box-sizing: border-box;margin-bottom: 15px;"><span style="font-size: 15px;">控制器应该是无状态的!默认情况下,控制器是单例,并且任何状态都可能导致大量问题;</span></p></li> <li style="box-sizing: border-box;margin-top: 2px !important;font-size: 15px;"><p style="box-sizing: border-box;margin-bottom: 15px;"><span style="font-size: 15px;">控制器不应该执行业务逻辑,而是依赖委托;</span></p></li> <li style="box-sizing: border-box;margin-top: 2px !important;font-size: 15px;"><p style="box-sizing: border-box;margin-bottom: 15px;"><span style="font-size: 15px;">控制器应该处理应用程序的 HTTP 层,这不应该传递给服务;</span></p></li> <li style="box-sizing: border-box;margin-top: 2px !important;font-size: 15px;"><p style="box-sizing: border-box;margin-bottom: 15px;"><span style="font-size: 15px;">控制器应该围绕用例 / 业务能力来设计。</span></p></li> </ul> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><span style="font-size: 15px;">要深入这个内容,需要进一步地了解设计 REST API 的最佳实践。无论你是否想要使用 Spring Boot,都是值得学习的。</span></p> <h3 style="box-sizing: border-box;margin-top: 2rem;margin-bottom: 0.5rem;font-weight: 700;color: rgb(255, 140, 0);line-height: 1.35;font-size: 18px;text-align: start;white-space: normal;font-family: Menlo, Monaco, 'Source Code Pro', Consolas, Inconsolata, 'Ubuntu Mono', 'DejaVu Sans Mono', 'Courier New', 'Droid Sans Mono', 'Hiragino Sans GB', 微软雅黑, monospace !important;"><span style="font-size: 15px;color: rgb(123, 12, 0);">7、围绕业务功能构建 @Service</span></h3> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><span style="font-size: 15px;">Service 是 Spring Boot 的另一个核心概念。我发现最好围绕业务功能 / 领域 / 用例(无论你怎么称呼都行)来构建服务。</span></p> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><span style="font-size: 15px;">在应用中设计名称类似</span><code style=""><span style="font-size: 15px;">AccountService</span></code><span style="font-size: 15px;">, </span><code style=""><span style="font-size: 15px;">UserService</span></code><span style="font-size: 15px;">, </span><code style=""><span style="font-size: 15px;">PaymentService</span></code><span style="font-size: 15px;">这样的服务,比起像</span><code style=""><span style="font-size: 15px;">DatabaseService</span></code><span style="font-size: 15px;">、</span><code style=""><span style="font-size: 15px;">ValidationService</span></code><span style="font-size: 15px;">、</span><code style=""><span style="font-size: 15px;">CalculationService</span></code><span style="font-size: 15px;">这样的会更合适一些。</span></p> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><span style="font-size: 15px;">你可以决定使用 Controler 和 Service 之间的一对一映射,那将是理想的情况。但这并不意味着,Service 之间不能互相调用!</span></p> <h3 style="box-sizing: border-box;margin-top: 2rem;margin-bottom: 0.5rem;font-weight: 700;color: rgb(255, 140, 0);line-height: 1.35;font-size: 18px;text-align: start;white-space: normal;font-family: Menlo, Monaco, 'Source Code Pro', Consolas, Inconsolata, 'Ubuntu Mono', 'DejaVu Sans Mono', 'Courier New', 'Droid Sans Mono', 'Hiragino Sans GB', 微软雅黑, monospace !important;"><span style="font-size: 15px;color: rgb(123, 12, 0);">8、使数据库独立于核心业务逻辑之外</span></h3> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><span style="font-size: 15px;">我之前还不确定如何在 Spring Boot 中最好地处理数据库交互。在阅读了罗伯特 ·C· 马丁的 “Clear Architecture” 之后,对我来说就清晰多了。</span></p> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><span style="font-size: 15px;">你希望你的数据库逻辑于服务分离出来。理想情况下,你不希望服务知道它正在与哪个数据库通信,这需要一些抽象来封装对象的持久性。</span></p> <blockquote style="box-sizing: border-box;margin-bottom: 1.2em;padding: 15px 15px 15px 1rem;color: rgb(129, 145, 152);border-left-width: 6px;border-left-color: rgb(96, 125, 139);font-size: 14px;line-height: 18px;background: rgb(242, 247, 251);font-family: Helvetica, Arial, sans-serif;text-align: start;white-space: normal;"> <p style="box-sizing: border-box;"><span style="font-size: 15px;">罗伯特 C. 马丁强烈地说明,你的数据库是一个 “细节”,这意味着不将你的应用程序与特定数据库耦合。过去很少有人会切换数据库,我注意到,使用 Spring Boot 和现代微服务开发会让事情变得更快。</span></p> </blockquote> <h3 style="box-sizing: border-box;margin-top: 2rem;margin-bottom: 0.5rem;font-weight: 700;color: rgb(255, 140, 0);line-height: 1.35;font-size: 18px;text-align: start;white-space: normal;font-family: Menlo, Monaco, 'Source Code Pro', Consolas, Inconsolata, 'Ubuntu Mono', 'DejaVu Sans Mono', 'Courier New', 'Droid Sans Mono', 'Hiragino Sans GB', 微软雅黑, monospace !important;"><span style="font-size: 15px;color: rgb(123, 12, 0);">9、保持业务逻辑不受 Spring Boot 代码的影响</span></h3> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><span style="font-size: 15px;">考虑到 “Clear Architecture” 的教训,你还应该保护你的业务逻辑。将各种 Spring Boot 代码混合在一起是非常诱人的…… 不要这样做。如果你能抵制诱惑,你将保持你的业务逻辑可重用。</span></p> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><span style="font-size: 15px;">部分服务通常成为库。如果不从代码中删除大量 Spring 注解,则更容易创建。</span></p> <h3 style="box-sizing: border-box;margin-top: 2rem;margin-bottom: 0.5rem;font-weight: 700;color: rgb(255, 140, 0);line-height: 1.35;font-size: 18px;text-align: start;white-space: normal;font-family: Menlo, Monaco, 'Source Code Pro', Consolas, Inconsolata, 'Ubuntu Mono', 'DejaVu Sans Mono', 'Courier New', 'Droid Sans Mono', 'Hiragino Sans GB', 微软雅黑, monospace !important;"><span style="font-size: 15px;color: rgb(123, 12, 0);">10、推荐使用构造函数注入</span></h3> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><span style="font-size: 15px;">这一条实践来自 Phil Webb(Spring Boot 的项目负责人, @phillip_webb)。</span></p> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><span style="font-size: 15px;">保持业务逻辑免受 Spring Boot 代码侵入的一种方法是使用构造函数注入。不仅是因为</span><code style=""><span style="font-size: 15px;">@Autowired</span></code><span style="font-size: 15px;">注解在构造函数上是可选的,而且还可以在没有 Spring 的情况下轻松实例化 bean。</span></p> <h3 style="box-sizing: border-box;margin-top: 2rem;margin-bottom: 0.5rem;font-weight: 700;color: rgb(255, 140, 0);line-height: 1.35;font-size: 18px;text-align: start;white-space: normal;font-family: Menlo, Monaco, 'Source Code Pro', Consolas, Inconsolata, 'Ubuntu Mono', 'DejaVu Sans Mono', 'Courier New', 'Droid Sans Mono', 'Hiragino Sans GB', 微软雅黑, monospace !important;"><span style="font-size: 15px;color: rgb(123, 12, 0);">11、熟悉并发模型</span></h3> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><span style="font-size: 15px;">我写过的最受欢迎的文章之一是 “介绍 Spring Boot 中的并发”。我认为这样做的原因是这个领域经常被误解和忽视。如果使用不当,就会出现问题。</span></p> <blockquote style="box-sizing: border-box;margin-bottom: 1.2em;padding: 15px 15px 15px 1rem;color: rgb(129, 145, 152);border-left-width: 6px;border-left-color: rgb(96, 125, 139);font-size: 14px;line-height: 18px;background: rgb(242, 247, 251);font-family: Helvetica, Arial, sans-serif;text-align: start;white-space: normal;"> <p style="box-sizing: border-box;"><span style="font-size: 15px;">https://www.e4developer.com/2018/03/30/introduction-to-concurrency-in-spring-boot/</span></p> </blockquote> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><span style="font-size: 15px;">在 Spring Boot 中,Controller 和 Service 是默认是单例。如果你不小心,这会引入可能的并发问题。你通常也在处理有限的线程池。请熟悉这些概念。</span></p> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><span style="font-size: 15px;">如果你正在使用新的 WebFlux 风格的 Spring Boot 应用程序,我已经解释了它在 “Spring’s WebFlux/Reactor Parallelism and Backpressure” 中是如何工作的。</span></p> <h3 style="box-sizing: border-box;margin-top: 2rem;margin-bottom: 0.5rem;font-weight: 700;color: rgb(255, 140, 0);line-height: 1.35;font-size: 18px;text-align: start;white-space: normal;font-family: Menlo, Monaco, 'Source Code Pro', Consolas, Inconsolata, 'Ubuntu Mono', 'DejaVu Sans Mono', 'Courier New', 'Droid Sans Mono', 'Hiragino Sans GB', 微软雅黑, monospace !important;"><span style="font-size: 15px;color: rgb(123, 12, 0);">12、加强配置管理的外部化</span></h3> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><span style="font-size: 15px;">这一点超出了 Spring Boot,虽然这是人们开始创建多个类似服务时常见的问题……</span></p> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><span style="font-size: 15px;">你可以手动处理 Spring 应用程序的配置。如果你正在处理多个 Spring Boot 应用程序,则需要使配置管理能力更加强大。</span></p> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><span style="font-size: 15px;">我推荐两种主要方法:</span></p> <ul style="padding-left: 20px;list-style: square;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;margin-top: 2px !important;" class="list-paddingleft-2"> <li style="box-sizing: border-box;margin-top: 2px !important;font-size: 15px;"><p style="box-sizing: border-box;margin-bottom: 15px;"><span style="font-size: 15px;">使用配置服务器,例如 Spring Cloud Config;</span></p></li> <li style="box-sizing: border-box;margin-top: 2px !important;font-size: 15px;"><p style="box-sizing: border-box;margin-bottom: 15px;"><span style="font-size: 15px;">将所有配置存储在环境变量中(可以基于 git 仓库进行配置)。</span></p></li> </ul> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><span style="font-size: 15px;">这些选项中的任何一个(第二个选项多一些)都要求你在 DevOps 更少工作量,但这在微服务领域是很常见的。</span></p> <h3 style="box-sizing: border-box;margin-top: 2rem;margin-bottom: 0.5rem;font-weight: 700;color: rgb(255, 140, 0);line-height: 1.35;font-size: 18px;text-align: start;white-space: normal;font-family: Menlo, Monaco, 'Source Code Pro', Consolas, Inconsolata, 'Ubuntu Mono', 'DejaVu Sans Mono', 'Courier New', 'Droid Sans Mono', 'Hiragino Sans GB', 微软雅黑, monospace !important;"><span style="font-size: 15px;color: rgb(123, 12, 0);">13、提供全局异常处理</span></h3> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><span style="font-size: 15px;">你真的需要一种处理异常的一致方法。Spring Boot 提供了两种主要方法:</span></p> <ul style="padding-left: 20px;list-style: square;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;margin-top: 2px !important;" class="list-paddingleft-2"> <li style="box-sizing: border-box;margin-top: 2px !important;font-size: 15px;"><p style="box-sizing: border-box;margin-bottom: 15px;"><span style="font-size: 15px;">你应该使用 HandlerExceptionResolver 定义全局异常处理策略;</span></p></li> <li style="box-sizing: border-box;margin-top: 2px !important;font-size: 15px;"><p style="box-sizing: border-box;margin-bottom: 15px;"><span style="font-size: 15px;">你也可以在控制器上添加 @ExceptionHandler 注解,这在某些特定场景下使用可能会很有用。</span></p></li> </ul> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><span style="font-size: 15px;">这与 Spring 中的几乎相同,并且 Baeldung 有一篇关于 REST 与 Spring 的错误处理的详细文章,非常值得一读。</span></p> <blockquote style="box-sizing: border-box;margin-bottom: 1.2em;padding: 15px 15px 15px 1rem;color: rgb(129, 145, 152);border-left-width: 6px;border-left-color: rgb(96, 125, 139);font-size: 14px;line-height: 18px;background: rgb(242, 247, 251);font-family: Helvetica, Arial, sans-serif;text-align: start;white-space: normal;"> <p style="box-sizing: border-box;"><span style="font-size: 15px;">https://www.baeldung.com/exception-handling-for-rest-with-spring</span></p> </blockquote> <h3 style="box-sizing: border-box;margin-top: 2rem;margin-bottom: 0.5rem;font-weight: 700;color: rgb(255, 140, 0);line-height: 1.35;font-size: 18px;text-align: start;white-space: normal;font-family: Menlo, Monaco, 'Source Code Pro', Consolas, Inconsolata, 'Ubuntu Mono', 'DejaVu Sans Mono', 'Courier New', 'Droid Sans Mono', 'Hiragino Sans GB', 微软雅黑, monospace !important;"><span style="font-size: 15px;color: rgb(123, 12, 0);">14、使用日志框架</span></h3> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><span style="font-size: 15px;">你可能已经意识到这一点,但你应该使用 Logger 进行日志记录,而不是使用 System.out.println() 手动执行。这很容易在 Spring Boot 中完成,几乎没有配置。只需获取该类的记录器实例:</span></p> <pre style="box-sizing: border-box;padding: 0.5em;font-family: Courier, 'Courier New', monospace;background: rgb(45, 45, 45);border-width: 1px;border-style: solid;border-color: rgb(221, 221, 221);overflow-x: auto;color: rgb(204, 204, 204);font-size: 15px;text-align: start;"><code style=""><span style="font-size: 15px;">Logger logger = LoggerFactory.getLogger(MyClass.class);<br></span></code></pre> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><span style="font-size: 15px;">这很重要,因为它可以让你根据需要设置不同的日志记录级别。</span></p> <h3 style="box-sizing: border-box;margin-top: 2rem;margin-bottom: 0.5rem;font-weight: 700;color: rgb(255, 140, 0);line-height: 1.35;font-size: 18px;text-align: start;white-space: normal;font-family: Menlo, Monaco, 'Source Code Pro', Consolas, Inconsolata, 'Ubuntu Mono', 'DejaVu Sans Mono', 'Courier New', 'Droid Sans Mono', 'Hiragino Sans GB', 微软雅黑, monospace !important;"><span style="font-size: 15px;color: rgb(123, 12, 0);">15、测试你的代码</span></h3> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><span style="font-size: 15px;">这不是 Spring Boot 特有的,但它需要提醒——测试你的代码!如果你没有编写测试,那么你将从一开始就编写遗留代码。</span></p> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><span style="font-size: 15px;">如果有其他人使用你的代码库,那边改变任何东西将会变得危险。当你有多个服务相互依赖时,这甚至可能更具风险。</span></p> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><span style="font-size: 15px;">由于存在 Spring Boot 最佳实践,因此你应该考虑将 Spring Cloud Contract 用于你的消费者驱动契约,它将使你与其他服务的集成更容易使用。</span></p> <h3 style="box-sizing: border-box;margin-top: 2rem;margin-bottom: 0.5rem;font-weight: 700;color: rgb(255, 140, 0);line-height: 1.35;font-size: 18px;text-align: start;white-space: normal;font-family: Menlo, Monaco, 'Source Code Pro', Consolas, Inconsolata, 'Ubuntu Mono', 'DejaVu Sans Mono', 'Courier New', 'Droid Sans Mono', 'Hiragino Sans GB', 微软雅黑, monospace !important;"><span style="font-size: 15px;color: rgb(123, 12, 0);">16、使用测试切片让测试更容易,并且更专注</span></h3> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><span style="font-size: 15px;">这一条实践来自 Madhura Bhave(Spring 开发者, @madhurabhave23)。</span></p> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><span style="font-size: 15px;">使用 Spring Boot 测试代码可能很棘手——你需要初始化数据层,连接大量服务,模拟事物…… 实际上并不是那么难!答案是使用测试切片。</span></p> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><span style="font-size: 15px;">使用测试切片,你可以根据需要仅连接部分应用程序。这可以为你节省大量时间,并确保你的测试不会与未使用的内容相关联。来自 spring.io 的一篇名为 Custom test slice with Spring test 1.4 的博客文章解释了这种技术。</span></p> <blockquote style="box-sizing: border-box;margin-bottom: 1.2em;padding: 15px 15px 15px 1rem;color: rgb(129, 145, 152);border-left-width: 6px;border-left-color: rgb(96, 125, 139);font-size: 14px;line-height: 18px;background: rgb(242, 247, 251);font-family: Helvetica, Arial, sans-serif;text-align: start;white-space: normal;"> <p style="box-sizing: border-box;"><span style="font-size: 15px;">https://spring.io/blog/2016/08/30/custom-test-slice-with-spring-boot-1-4</span></p> </blockquote> <h3 style="box-sizing: border-box;margin-top: 2rem;margin-bottom: 0.5rem;font-weight: 700;color: rgb(255, 140, 0);line-height: 1.35;font-size: 18px;text-align: start;white-space: normal;font-family: Menlo, Monaco, 'Source Code Pro', Consolas, Inconsolata, 'Ubuntu Mono', 'DejaVu Sans Mono', 'Courier New', 'Droid Sans Mono', 'Hiragino Sans GB', 微软雅黑, monospace !important;"><span style="font-size: 15px;color: rgb(123, 12, 0);">总结</span></h3> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><span style="font-size: 15px;">感谢 Spring Boot,编写基于 Spring 的微服务正变得前所未有的简单。我希望通过这些最佳实践,你的实施过程不仅会变得很快,而且从长远来看也会更加强大和成功。祝你好运!</span></p> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><span style="font-size: 15px;"><br></span></p> <section data-mpa-template="t" mpa-from-tpl="t" style="font-family: -apple-system-font, system-ui, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);font-size: 16px;text-align: left;color: rgb(120, 114, 114);widows: 1;word-spacing: 2px;"> <section data-id="89429" mpa-from-tpl="t" style="border-width: 0px;border-style: none;border-color: initial;"> <section mpa-from-tpl="t" style="text-align: center;height: 50px;"> <section mpa-from-tpl="t" style="margin-right: auto;margin-left: auto;width: 48px;height: 48px;color: rgb(255, 255, 255);line-height: 48px;display: inline-block;background-image: url("https://mmbiz.qpic.cn/mmbiz_gif/kiaqiahsnxHd4Zt4378tqib1DnnfKYvZAI7sUNZCYmGN2HCMDFDYV5hLu6HrHIK5BynAAwgHGiafFFU7ibYez6mXL4w/640?wx_fmt=gif");background-repeat: no-repeat;background-size: 100%;background-position: 0px center;"> <p style="font-weight: bold;"><span style="font-size: 14px;">end</span></p> </section> <section mpa-from-tpl="t" style="margin-top: -26px;height: 2px;background-color: rgb(34, 33, 33);"> <br> </section> </section> </section> </section> <p style="font-family: -apple-system-font, system-ui, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);"><br></p> <section mpa-from-tpl="t" style="padding-left: 5px;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(62, 62, 62);font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-size: medium;text-align: left;widows: 1;word-spacing: 2px;border-left: 5px solid rgb(51, 51, 51);line-height: 1.5em;"> <section powered-by="xiumi.us" mpa-from-tpl="t"> <section mpa-from-tpl="t"> <section mpa-from-tpl="t" style="font-size: 18px;"> <p><span style="font-size: 16px;">推荐阅读:</span></p> </section> </section> </section> </section> <ul class="list-paddingleft-2" mpa-from-tpl="t" style="letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(62, 62, 62);font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-size: medium;text-align: left;widows: 1;word-spacing: 2px;"> <li style="font-size: 14px;"><p style="margin-top: 5px;"><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzA3ODIxNjYxNQ==&mid=2247491979&idx=1&sn=b92304d84be599c249c2f289564ecceb&chksm=9f448d43a833045522332a4f0c5d4ced264ff340a86e99b306f05e79cd107da48722cfade523&scene=21#wechat_redirect" data-itemshowtype="0" tab="innerlink" data-linktype="2" hasload="1" style="color: var(--weui-LINK);-webkit-tap-highlight-color: rgba(0, 0, 0, 0);cursor: pointer;">CTO 说公司的 ES 性能不够好、集群不够稳定!直到我用了这些调优技巧后。。。</a><br></p></li> <li style="font-size: 14px;"><p style="margin-top: 5px;"><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzA3ODIxNjYxNQ==&mid=2247491966&idx=1&sn=19574092666f433c901964991c3d84b2&chksm=9f448db6a83304a090ce3b8392d95b66c105f656171dab8ef7c3062c409e3c89a79eca646bf8&scene=21#wechat_redirect" data-itemshowtype="0" tab="innerlink" data-linktype="2" hasload="1" style="color: var(--weui-LINK);-webkit-tap-highlight-color: rgba(0, 0, 0, 0);cursor: pointer;">谈谈微服务设计中的API网关模式</a><br></p></li> <li style="font-size: 14px;"><p style="margin-top: 5px;"><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzA3ODIxNjYxNQ==&mid=2247491193&idx=1&sn=780ee5479d8eec22dbd3f573589ae80e&chksm=9f4772b1a830fba79ca6e136e45ed5e8bba822934747ef09d8c3ffe2fc8fb80116ee717b5111&scene=21#wechat_redirect" data-itemshowtype="0" tab="innerlink" data-linktype="2" hasload="1" style="color: var(--weui-LINK);-webkit-tap-highlight-color: rgba(0, 0, 0, 0);cursor: pointer;">终于有人把 Docker 讲清楚了,别再说不会 Docker 了!</a><br></p></li> <li style="font-size: 14px;"><p style="margin-top: 5px;"><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzA3ODIxNjYxNQ==&mid=2247489178&idx=1&sn=7f7f730d290e8d09f1d83af674655f41&chksm=9f477a52a830f344a6e9cd916706c5bb9e88064baba787345feb076d70fd7a9fbfb16873fa9a&scene=21#wechat_redirect" data-itemshowtype="0" tab="innerlink" data-linktype="2" hasload="1" style="color: var(--weui-LINK);-webkit-tap-highlight-color: rgba(0, 0, 0, 0);cursor: pointer;">前后端分离模式下的权限设计方案</a></p></li> <li style="font-size: 14px;"><p style="margin-top: 5px;"><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzA3ODIxNjYxNQ==&mid=2247489451&idx=1&sn=ce18154070fc3d868750bfca5dd6e5ba&chksm=9f477b63a830f275f4c3d1ddee3b352e67348069f142ecb3e1cf479c13054869f3a7e405cc5b&scene=21#wechat_redirect" data-itemshowtype="0" tab="innerlink" data-linktype="2" hasload="1" style="color: var(--weui-LINK);-webkit-tap-highlight-color: rgba(0, 0, 0, 0);cursor: pointer;">究竟什么是图数据库,它有哪些应用场景?</a></p></li> </ul> <p style="margin-top: 5px;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(62, 62, 62);font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;text-align: left;widows: 1;word-spacing: 2px;"><br></p> <p style="margin-top: 5px;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(62, 62, 62);font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;widows: 1;word-spacing: 2px;text-align: right;"><img class="rich_pages" data-ratio="0.5555555555555556" data-s="300,640" data-type="jpeg" data-w="900" src="/upload/9d786e52e671b1ce4beb338d1e0d1815.jpg" style="letter-spacing: 0.544px;text-align: center;font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;box-sizing: border-box !important;visibility: visible !important;width: 677px !important;"><span style="letter-spacing: 0.544px;font-size: 14px;">如有收获,点个在看,诚挚感谢</span><img data-ratio="1" data-type="png" data-w="19" width="19px" src="/upload/5f7454d24a334e968c32b8ce9ae53c5.png" style="font-size: 16px;letter-spacing: 0.544px;display: inline-block;vertical-align: text-bottom;box-sizing: border-box !important;visibility: visible !important;width: 19px !important;"></p> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;"><br></p> <pre style="background-color: rgb(255, 255, 255);font-size: 15px;letter-spacing: 0.544px;text-align: start;color: rgb(62, 62, 62);widows: 1;word-spacing: 1px;caret-color: rgb(51, 51, 51);"></pre>
作者:微信小助手
<section style="box-sizing: border-box;font-style: normal;font-weight: 400;text-align: justify;font-size: 16px;"> <section style="margin-top: 10px;margin-bottom: 10px;box-sizing: border-box;"> <section style="padding: 10px 10px 0px;background-color: rgb(239, 239, 239);box-sizing: border-box;"> <span style="display: inline-block;width: 5%;line-height: 0.8;font-weight: bolder;font-size: 48px;box-sizing: border-box;" title=""> <section style="box-sizing: border-box;"> “ </section></span> <section style="display: inline-block;vertical-align: top;float: right;width: 90%;line-height: 1.5;font-size: 15px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="margin: 0px;padding: 0px;box-sizing: border-box;"><span style="letter-spacing: 1px;">最近几年微服务很火,大家都在建设微服务,如果不懂点微服务相关的技术,都不好意思跟同行打招呼了。</span></p> </section> <section style="clear: both;box-sizing: border-box;"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> </section> </section> </section> <p style="line-height: 1.75em;"><br></p> <section style="text-align: center;margin-left: 8px;margin-right: 8px;"> <img class="rich_pages" data-ratio="0.6592741935483871" data-s="300,640" src="/upload/5333f9788dc79b04dd350883eceba4d2.png" data-type="png" data-w="992" style=""> </section> <section style="text-align: center;line-height: 1.75em;"> <span style="font-size: 14px;color: rgb(89, 89, 89);letter-spacing: 1px;"><em>图片来自 Pexels</em></span> <br> </section> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">我也见过身边很多人在微服务踩过很多坑,我从 2016 年开始接触微服务,有多家大型企业的微服务分布式系统的架构经验,不过微服务和涉及的分布式计算非常的复杂,绝非是一篇文章就可以讲清楚的。<br></span></p> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">本文只是从最简单的概念的基本使用带你入门,如果后续还有兴趣的话,可以查阅相关的文献和技术书籍去深入学习。</span></p> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">本文的微服务分享以下三部分,总体大纲如下:</span></p> <ul style="list-style-type: disc;" class="list-paddingleft-2"> <li style="font-weight: bold;"> <section style="line-height: 1.75em;"> <strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">微服务的概念和原则(理论)</span></strong> </section></li> <li style="font-weight: bold;"> <section style="line-height: 1.75em;"> <strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">Spring Cloud 如何低成本的实现微服务(实现)</span></strong> </section></li> <li style="font-weight: bold;"> <section style="line-height: 1.75em;"> <strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">Spring Cloud 大型项目的架构方案(真实案例)</span></strong> </section></li> </ul> <p style="line-height: normal;"><br></p> <section> <section> <section> <section style="box-sizing: border-box;font-style: normal;font-weight: 400;text-align: justify;font-size: 16px;"> <section style="border-bottom: 1px solid black;margin: 0.5em 0px;line-height: 1.2;box-sizing: border-box;"> <section style="display: inline-block;border-color: rgb(89, 89, 89);border-bottom: 6px solid rgb(89, 89, 89);margin-bottom: -1px;font-size: 20px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="margin: 0px;padding: 0px;box-sizing: border-box;">微服务的概念和原则<br></p> </section> </section> </section> </section> </section> </section> <section> <section> <section> <section> <section> <section style="line-height: normal;"> <br> </section> <section> <section> <section> <section style="box-sizing: border-box;font-style: normal;font-weight: 400;text-align: justify;font-size: 16px;"> <section style="margin-top: 10px;margin-bottom: 10px;box-sizing: border-box;"> <section style="width: 0.6em;display: inline-block;vertical-align: middle;box-sizing: border-box;"> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.2;background-color: rgb(89, 89, 89);box-sizing: border-box;"></span> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.6;margin: 2px 0px;background-color: rgb(89, 89, 89);box-sizing: border-box;"></span> <strong><span style="width: 0.6em;height: 0.6em;display: block;opacity: 1;background-color: rgb(89, 89, 89);box-sizing: border-box;"></span> </strong> </section> <section style="display: inline-block;vertical-align: middle;font-size: 18px;padding-left: 5px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="margin: 0px;padding: 0px;box-sizing: border-box;"><strong>什么是微服务?</strong></p> </section> </section> </section> <p style="line-height: normal;"><br></p> </section> </section> </section> </section> </section> </section> </section> </section> <h5 style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">简单举例:</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">看军事新闻的同学应该都知道,一艘航空母舰作战能力虽然很强,但是弱点太明显,就是防御能力太差,单艘的航空母舰很少单独行动,通常航空母舰战斗群才是主要军事力量。</span></h5> <h5 style="line-height: normal;"><br></h5> <h5 style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">你可以把单艘航母理解为的单体应用(防御差,机动性不好),把航母战斗群(调度复杂,维护费用高)理解为微服务。</span></h5> <p style="line-height: normal;"><br></p> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">简单讲特征就是:</span> </section> <ul style="list-style-type: disc;" class="list-paddingleft-2"> <li> <section style="line-height: 1.75em;"> <strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">单体应用:</span></strong> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">简单,脆弱(某个模块出问题,整个系统不可用),战斗力弱,维护成本低。</span> </section></li> <li> <section style="margin-bottom: 5px;line-height: 1.75em;"> <strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">微服务架构:</span></strong> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">复杂,健壮(某个模块出问题,不会影响系统整体的可用性),战斗力强,维护成本高。</span> <br> </section></li> </ul> <p style="text-align: center;margin-left: 8px;margin-right: 8px;margin-bottom: 5px;"><img class="rich_pages" data-ratio="0.75" data-s="300,640" src="/upload/a422e69baf4a96ae0d0820c664d13822.jpg" data-type="jpeg" data-w="1080" style=""></p> <section style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"> <span style="font-size: 14px;"><em><span style="color: rgb(89, 89, 89);letter-spacing: 1px;">单体作战的应用(图)</span></em></span> <br> </section> <p style="text-align: center;margin-left: 8px;margin-right: 8px;margin-bottom: 5px;"><img class="rich_pages" data-ratio="0.5138888888888888" data-s="300,640" src="/upload/e8f8915538f18035c174dd56b7ecc790.jpg" data-type="jpeg" data-w="1080" style=""></p> <section style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 14px;"><em><span style="color: rgb(89, 89, 89);letter-spacing: 1px;">微服务战斗群(图)</span></em></span> <br> </section> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">大部分的开发者经历和开发过单体应用,无论是传统的 SSM,还是现在的 Spring Boot/Rails,它们都是单体应用。<br></span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">那么长期陪伴我们的单体应用有什么弊端?我们是面临了什么问题,导致我们要抛弃单体应用转向微服务架构?<br></span></p> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">个人总结主要问题如下:</span></p> <ul style="list-style-type: disc;" class="list-paddingleft-2"> <li><p style="line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">部署成本高(无论是修改 1 行代码,还是 10 行代码,都要全量部署替换)。</span></p></li> <li><p style="line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">改动影响大,风险高,测试成本高(不论代码改动多小,成本都相同)。</span></p></li> <li><p style="line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">因为成本高,风险高,所以导致部署频率低(无法满足快速交付客户需求)。</span></p></li> </ul> <section style="line-height: normal;"> <br> </section> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">当然还有例如无法满足快速扩容,弹性伸缩,无法适应云环境特性等问题,但我们不一一详谈了,以上的问题,都是微服务架构要解决的问题,至于具体是怎么解决的,我们先放到后面再聊。</span> <br> </section> <section style="text-align: center;margin-bottom: 5px;margin-left: 8px;margin-right: 8px;"> <img class="rich_pages" data-ratio="0.5166666666666667" data-s="300,640" src="/upload/e408a037705ab403d9d19edf9ef1a917.jpg" data-type="jpeg" data-w="1080" style=""> </section> <section style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 14px;letter-spacing: 1px;"><em><span style="color: rgb(89, 89, 89);">历代应用程序的架构变迁(图)</span></em></span> <br> </section> <p style="line-height: normal;"><br></p> <section> <section> <section> <section> <section> <section> <section> <section style="box-sizing: border-box;font-style: normal;font-weight: 400;text-align: justify;font-size: 16px;"> <section style="margin-top: 10px;margin-bottom: 10px;box-sizing: border-box;"> <section style="width: 0.6em;display: inline-block;vertical-align: middle;box-sizing: border-box;"> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.2;background-color: rgb(89, 89, 89);box-sizing: border-box;"></span> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.6;margin: 2px 0px;background-color: rgb(89, 89, 89);box-sizing: border-box;"></span> <strong><span style="width: 0.6em;height: 0.6em;display: block;opacity: 1;background-color: rgb(89, 89, 89);box-sizing: border-box;"></span> </strong> </section> <section style="display: inline-block;vertical-align: middle;font-size: 18px;padding-left: 5px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="margin: 0px;padding: 0px;box-sizing: border-box;"><strong>解决什么问题,又引入了什么问题?</strong></p> </section> </section> </section> <p style="line-height: normal;"><br></p> </section> </section> </section> </section> </section> </section> </section> <h5 style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">我们先看看微服务能带给我们什么?微服务架构的特点:</span></h5> <ul style="list-style-type: disc;" class="list-paddingleft-2"> <li><h5 style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">针对特定服务发布,影响小,风险小,成本低</span></strong></h5></li> <li><h5 style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">频繁发布版本,快速交付需求</span></strong></h5></li> <li><h5 style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">低成本扩容,弹性伸缩,适应云环境</span></strong></h5></li> </ul> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">我们知道一个朴素的理念,没有任何事物是完美的,任何东西都有两面性,有得必有失。<br></span></p> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">那么在选择微服务在解决了快速响应和弹性伸缩的问题同时,它又给我们带来了什么问题?</span></p> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">个人总结如下:</span></p> <ul style="list-style-type: disc;" class="list-paddingleft-2"> <li style="font-weight: bold;"> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">分布式系统的复杂性</span></strong> </section></li> <li style="font-weight: bold;"> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">部署,测试和监控的成本问题</span></strong> </section></li> <li style="font-weight: bold;"> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">分布式事务和 CAP 的相关问题</span></strong> </section></li> </ul> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">系统应用由原来的单体变成几十到几百个不同的工程,会所产生例如包括服务间的依赖,服务如何拆封,内部接口规范,数据传递等等问题。<br></span></p> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">尤其是服务拆分,需要团队熟悉业务流程,懂得取舍,要保证拆分的粒度服务既符合“高内聚,低耦合”的基本原则,还要兼顾业务的发展以及公司的愿景,要还要说服团队成员为之努力,并且积极投入,在多方中间取得平衡。<br></span></p> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">对于分布式系统,部署,测试和监控都需要大量的中间件来支撑,而且中间件本身也要维护。<br></span></p> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">原先单体应用很简单的事务问题 ,转到分布式环境就变得很复杂,分布式事务是采用简单的重试+补偿机制,还是采用二阶段提交协议等强一致性方法来解决,就要取决对业务场景的熟悉加上反复的权衡了。<br></span></p> <section style="line-height: normal;"> <br> </section> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">相同问题还包括对 CAP 模型的权衡,总之微服务对团队整体的技术栈水平整体要求更高。<br></span> </section> <p style="text-align: center;margin-bottom: 5px;margin-left: 8px;margin-right: 8px;"><img class="rich_pages" data-ratio="0.388" data-s="300,640" src="/upload/ea43e5073842a1894fc88422a0900d5f.jpg" data-type="jpeg" data-w="1000" style=""></p> <section> <section> <section> <section> <section> <section> <section> <section> <section> <section style="box-sizing: border-box;font-style: normal;font-weight: 400;text-align: justify;font-size: 16px;"> <section style="margin-top: 10px;margin-bottom: 10px;box-sizing: border-box;"> <section style="width: 0.6em;display: inline-block;vertical-align: middle;box-sizing: border-box;"> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.2;background-color: rgb(89, 89, 89);box-sizing: border-box;"></span> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.6;margin: 2px 0px;background-color: rgb(89, 89, 89);box-sizing: border-box;"></span> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 1;background-color: rgb(89, 89, 89);box-sizing: border-box;"></span> </section> <section style="display: inline-block;vertical-align: middle;font-size: 18px;padding-left: 5px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="margin: 0px;padding: 0px;box-sizing: border-box;"><strong>微服务有哪些应该遵循哪些原则?</strong></p> </section> </section> </section> <section style="line-height: normal;"> <br> </section> </section> </section> </section> </section> </section> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">古人云:兵马未动,粮草先行。建设微服务是需要建立长远规划,不是像写 CMS 那样建好数据库表,然后就开始干活,这样十有八九是会失败的。<br></span></p> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">我们要进行微服务改造前,架构师要提前做好规划,我们把这里分为三步,前期阶段,设计阶段,技术阶段。</span><br></p> <section style="line-height: normal;"> <br> </section> </section> </section> </section> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">前期阶段,大致要做好如下事情:</span> </section> <ul style="list-style-type: disc;" class="list-paddingleft-2"> <li> <section style="line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">和多方充分沟通,确保能符合客户和组织的需求,并且得到认同。</span> </section></li> <li> <section style="line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">和团队沟通,让队友(开发/测试/运维)理解,并且积极投入。</span> </section></li> <li> <section style="line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">和业务部门沟通,指定版本计划和上线时间。</span> </section></li> </ul> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">设计阶段,参考 Sam Newman 的著作《微服务设计》,单微服务必须要满足以下的条件,</span><span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">才符合微服务的基本要求:</span></p> <ul style="list-style-type: disc;" class="list-paddingleft-2"> <li> <section style="line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">标准的 REST 风格接口(基于 HTTP 和 JSON 格式)。</span> </section></li> <li> <section style="line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">独立部署,避免共享数据库(避免因为数据库而影响整个分布式系统)。</span> </section></li> <li> <section style="line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">业务上的高内聚,减少依赖(从设计上要避免服务过大或者太小)。</span> </section></li> </ul> <p style="text-align: justify;line-height: normal;"><br></p> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">庞大的分布式系统,需要强大基础设施来支撑,微服务涉及哪些基础设施?</span> </section> <ul style="list-style-type: disc;" class="list-paddingleft-2"> <li> <section style="line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">CI/CD 和自动化(分布式系统几乎不可能通过人工手动发布。)</span> </section></li> <li> <section style="line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">虚拟化技术(要保证微服务运行环境隔离,目前行业主流的是使用 Docker 容器)。</span> </section></li> <li> <section style="line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">日志聚合,全链路监控(高度可观察和分析诊断问题)。</span> </section></li> </ul> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">说了那么多,那什么样的情况下,你的团队不适合建设微服务?(请勿对号入座)</span></p> <ul style="list-style-type: disc;" class="list-paddingleft-2"> <li> <section style="line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">开发团队不具备自主性,所在组织对开发团队限制非常多(具体请参考 康威定律)。</span> </section></li> <li> <section style="line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">团队不熟悉业务,无法识别出服务的边界,进行合理的拆分(请参考 DDD 领域驱动设计)。</span> </section></li> </ul> <section style="line-height: normal;"> <br> </section> <p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">微服务设计其实是很早就有的设计思想,因为随着虚拟化技术的崛起,微服务可以低成本的实现,所以也开始流行和兴起。<br></span></p> <section style="line-height: normal;"> <br> </section> <p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">微服务的内涵很深,其中就包括,自动化,去中心化,独立性等等,其中细节无法用一篇文章概述清楚,我们在做技术选型或者方案的时候,尽可能多去了解技术的本身和起源再结合我们业务的特点,进行更好的选择。</span></p> <p style="line-height: normal;"><br></p> <section style="box-sizing: border-box;font-style: normal;font-weight: 400;text-align: justify;font-size: 16px;"> <section style="border-bottom: 1px solid black;margin: 0.5em 0px;line-height: 1.2;box-sizing: border-box;"> <section style="display: inline-block;border-color: rgb(89, 89, 89);border-bottom: 6px solid rgb(89, 89, 89);margin-bottom: -1px;font-size: 20px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="margin: 0px;padding: 0px;box-sizing: border-box;">如何低成本的实现微服务?</p> </section> </section> </section> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;marg
作者:微信小助手
<section style="white-space: normal;text-align: center;" data-mpa-powered-by="yiban.io"> <span style="font-size: 13px;color: rgb(136, 136, 136);font-family: Georgia, "Times New Roman", Times, "Songti SC", serif;letter-spacing: 0.544px;">点击上方蓝色“</span> <span style="font-size: 13px;font-family: Georgia, "Times New Roman", Times, "Songti SC", serif;letter-spacing: 0.544px;color: rgb(0, 128, 255);">程序猿DD</span> <span style="font-size: 13px;color: rgb(136, 136, 136);font-family: Georgia, "Times New Roman", Times, "Songti SC", serif;letter-spacing: 0.544px;">”,选择“设为星标”</span> <strong style="letter-spacing: 0.544px;color: rgb(74, 74, 74);font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif;font-size: 16px;white-space: pre-line;background-color: rgb(255, 255, 255);text-align: right;"></strong> </section> <section style="white-space: normal;min-height: 1em;text-align: center;"> <span style="font-size: 13px;"><span style="color: rgb(136, 136, 136);font-family: Georgia, "Times New Roman", Times, "Songti SC", serif;letter-spacing: 0.544px;">回复“</span><span style="font-family: Georgia, "Times New Roman", Times, "Songti SC", serif;letter-spacing: 0.544px;color: rgb(0, 128, 255);">资源</span><span style="color: rgb(136, 136, 136);font-family: Georgia, "Times New Roman", Times, "Songti SC", serif;letter-spacing: 0.544px;">”获取独家整理的学习资料!</span></span> </section> <section style="margin-top: 10px;margin-bottom: 10px;white-space: normal;min-height: 1em;text-align: center;"> <span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;"></span> <span style="color: rgb(136, 136, 136);font-family: Georgia, "Times New Roman", Times, "Songti SC", serif;font-size: 14px;letter-spacing: 0.544px;"><img data-backh="34" data-backw="540" data-ratio="0.0625" data-s="300,640" data-type="jpeg" data-w="640" width="100%" src="/upload/8c292e55ba5a23cb6ebc11f2a2c4fece.jpg" style="font-family: -apple-system-font, system-ui, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;box-sizing: border-box !important;visibility: visible !important;width: 654px !important;"></span> </section> <p style="text-align: center;"><img class="rich_pages" data-ratio="0.56171875" data-s="300,640" src="/upload/5c4e9af11d648601a1becb648a516612.jpg" data-type="jpeg" data-w="1280" style=""></p> <section style="white-space: normal;"> <span style="color: rgb(178, 178, 178);font-size: 13px;">来源:<span style="font-size: 13px;color: rgb(178, 178, 178);font-family: -apple-system-font, system-ui, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-align: left;background-color: rgb(255, 255, 255);">https://blog.csdn.net/vbirdbest/article/details/80207673</span></span> <br> </section> <section data-tool="mdnice编辑器" data-website="https://www.mdnice.com" style="font-family: -apple-system-font, system-ui, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);"> <p style="margin: 1em 8px;font-size: inherit;line-height: 1.6 !important;"><span style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;"><strong style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;">一:简洁</strong><br></span></p> </section> <section data-tool="mdnice编辑器" data-website="https://www.mdnice.com" style="font-family: -apple-system-font, system-ui, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);"> <section style="margin-bottom: 5px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: rgb(89, 89, 89);"> <span style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;">方法引用分为三种,方法引用通过一对双冒号:: 来表示,方法引用是一种函数式接口的另一种书写方式</span> </section> <ul class="list-paddingleft-2"> <li><p style="margin-top: 5px;margin-bottom: 5px;padding-top: 8px;padding-bottom: 8px;color: rgb(89, 89, 89);line-height: normal;"><span style="font-family: Optima-Regular, PingFangTC-light;font-size: 15px;">静态方法引用,</span><span style="font-family: Optima-Regular, PingFangTC-light;font-size: 15px;">通过类名::静态方法名, 如 Integer::parseInt</span></p></li> <li><p style="margin-top: 5px;margin-bottom: 5px;padding-top: 8px;padding-bottom: 8px;color: rgb(89, 89, 89);line-height: normal;"><span style="font-family: Optima-Regular, PingFangTC-light;font-size: 15px;">实例方法引用,通过实例对象::实例方法,如 str::substring</span></p></li> <li><p style="margin-top: 5px;margin-bottom: 5px;padding-top: 8px;padding-bottom: 8px;color: rgb(89, 89, 89);line-height: normal;"><span style="font-family: Optima-Regular, PingFangTC-light;font-size: 15px;">构造方法引用,通过类名::new, 如 User::new</span></p></li> </ul> <h1 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 24px;color: rgb(89, 89, 89);"><span style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;">二:方法引用</span></h1> <section data-mpa-preserve-tpl-color="t" data-mpa-template="t" mpa-preserve="t" mpa-from-tpl="t"> <pre style="background: none;"><code style="margin-right: 0.15em;margin-left: 0.15em;padding: 5.95px;border-radius: 4px;font-size: 0.85em;background: rgb(248, 248, 248);display
作者:微信小助手
<p data-mpa-powered-by="yiban.io" style="max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(62, 71, 83);font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;text-align: center;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-family: Optima-Regular, PingFangTC-light;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 16px;letter-spacing: 0.544px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;color: rgb(127, 127, 127);font-size: 14px;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;">点击上方“</span><span style="max-width: 100%;font-size: 14px;line-height: 1.75em;color: rgb(0, 176, 240);box-sizing: border-box !important;overflow-wrap: break-word !important;">服务端思维</span><span style="max-width: 100%;color: rgb(127, 127, 127);font-size: 14px;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;">”,选择“</span></span><span style="max-width: 100%;color: rgb(136, 136, 136);font-size: 14px;box-sizing: border-box !important;overflow-wrap: break-word !important;">设为星标</span><span style="max-width: 100%;color: rgb(127, 127, 127);letter-spacing: 0.544px;font-size: 14px;box-sizing: border-box !important;overflow-wrap: break-word !important;">”</span></span></p> <p style="max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;color: rgb(62, 62, 62);font-size: 15px;text-align: center;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-family: Optima-Regular, PingFangTC-light;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;letter-spacing: 0.544px;color: rgb(127, 127, 127);font-size: 14px;box-sizing: border-box !important;overflow-wrap: break-word !important;">回复”</span><span style="max-width: 100%;letter-spacing: 0.544px;font-size: 14px;color: rgb(0, 122, 170);box-sizing: border-box !important;overflow-wrap: break-word !important;">669</span><span style="max-width: 100%;letter-spacing: 0.544px;color: rgb(127, 127, 127);font-size: 14px;box-sizing: border-box !important;overflow-wrap: break-word !important;">“获取独家整理的精选资料集</span></span></p> <p style="max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;color: rgb(62, 62, 62);font-size: 15px;text-align: center;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-family: Optima-Regular, PingFangTC-light;letter-spacing: 0.544px;color: rgb(127, 127, 127);font-size: 14px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;letter-spacing: 0.544px;box-sizing: border-box !important;overflow-wrap: break-word !important;">回复”</span><span style="max-width: 100%;letter-spacing: 0.544px;color: rgb(0, 122, 170);box-sizing: border-box !important;overflow-wrap: break-word !important;">加群</span><span style="max-width: 100%;letter-spacing: 0.544px;box-sizing: border-box !important;overflow-wrap: break-word !important;">“加入全国服务端高端社群「后端圈」</span></span></p> <p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-backh="325" data-backw="579" data-ratio="0.5625" data-s="300,640" src="/upload/f837fde7657edcd2080e32c9a589a074.jpg" data-type="jpeg" data-w="1280" style="width: 100%;height: auto;"></p> <header style="overflow: hidden;width: 690px;margin-right: auto;margin-left: auto;color: rgb(18, 18, 18);font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;font-size: medium;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);"> <p style="margin-bottom: 1.4em;color: rgb(18, 18, 18);font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;font-size: medium;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);"><span style="font-weight: 600;">Redis 数据库内存数据满了,会宕机吗?</span></p> <p style="margin-top: 1.4em;margin-bottom: 1.4em;color: rgb(18, 18, 18);font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;font-size: medium;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">答案是:不会让它出现存满的情况,在使用Redis的时候我们要配置Redis能使用的最大的内存大小,存到一定容量的时候还有Redis的内存淘汰策略呢,还有LRU算法进行淘汰,等等。。。</p> <p style="margin-top: 1.4em;margin-bottom: 1.4em;color: rgb(18, 18, 18);font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;font-size: medium;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">接下来一起探讨下,Redis的内存淘汰策略。<br></p> <h3 style="margin-top: 1.90909em;margin-bottom: 1.27273em;font-variant-numeric: inherit;font-weight: 600;font-stretch: inherit;font-size: 1.1em;line-height: 1.5;font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;clear: left;color: rgb(18, 18, 18);text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">Redis占用内存大小</h3> <p style="margin-top: 1.4em;margin-bottom: 1.4em;color: rgb(18, 18, 18);font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;font-size: medium;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">我们知道Redis是基于内存的key-value数据库,因为系统的内存大小有限,所以我们在使用Redis的时候可以配置Redis能使用的最大的内存大小。</p> <h3 style="margin-top: 1.90909em;margin-bottom: 1.27273em;font-variant-numeric: inherit;font-weight: 600;font-stretch: inherit;font-size: 1.1em;line-height: 1.5;font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;clear: left;color: rgb(18, 18, 18);text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">1、通过配置文件配置</h3> <p style="margin-top: 1.4em;margin-bottom: 1.4em;color: rgb(18, 18, 18);font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;font-size: medium;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">通过在Redis安装目录下面的redis.conf配置文件中添加以下配置设置内存大小</p> <pre style="padding: 0.88889em;font-size: 0.9em;word-break: normal;overflow-wrap: normal;overflow: auto;background: rgb(246, 246, 246);border-radius: 4px;"><code style="border-radius: 0px;font-family: Menlo, Monaco, Consolas, "Andale Mono", "lucida console", "Courier New", monospace;font-size: inherit;background-color: inherit;">//设置Redis最大占用内存大小为100M<br>maxmemory 100mb</code></pre> <blockquote style="margin-top: 1.4em;margin-bottom: 1.4em;padding-left: 1em;color: rgb(100, 100, 100);border-left-color: rgb(211, 211, 211);font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;font-size: medium;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);"> redis的配置文件不一定使用的是安装目录下面的redis.conf文件,启动redis服务的时候是可以传一个参数指定redis的配置文件的 </blockquote> <h3 style="margin-top: 1.90909em;margin-bottom: 1.27273em;font-variant-numeric: inherit;font-weight: 600;font-stretch: inherit;font-size: 1.1em;line-height: 1.5;font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;clear: left;color: rgb(18, 18, 18);text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">2、通过命令修改</h3> <p style="margin-top: 1.4em;margin-bottom: 1.4em;color: rgb(18, 18, 18);font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;font-size: medium;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">Redis支持运行时通过命令动态修改内存大小</p> <pre style="padding: 0.88889em;font-size: 0.9em;word-break: normal;overflow-wrap: normal;overflow: auto;background: rgb(246, 246, 246);border-radius: 4px;"><code style="border-radius: 0px;font-family: Menlo, Monaco, Consolas, "Andale Mono", "lucida console", "Courier New", monospace;font-size: inherit;background-color: inherit;">//设置Redis最大占用内存大小为100M`<br><br>127.0.0.1:6379> config set maxmemory 100mb`<br><br>//获取设置的Redis能使用的最大内存大小`<br><br>127.0.0.1:6379> config get maxmemory`</code></pre> <p style="margin-top: -0.8em;margin-bottom: -0.8em;color: rgb(18, 18, 18);font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;font-size: medium;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);"><br></p> <blockquote style="margin-top: 1.4em;margin-bottom: 1.4em;padding-left: 1em;color: rgb(100, 100, 100);border-left-color: rgb(211, 211, 211);font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;font-size: medium;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);"> 如果不设置最大内存大小或者设置最大内存大小为0,在64位操作系统下不限制内存大小,在32位操作系统下最多使用3GB内存 </blockquote> <h3 style="margin-top: 1.90909em;margin-bottom: 1.27273em;font-variant-numeric: inherit;font-weight: 600;font-stretch: inherit;font-size: 1.1em;line-height: 1.5;font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;clear: left;color: rgb(18, 18, 18);text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">Redis的内存淘汰</h3> <p style="margin-top: 1.4em;margin-bottom: 1.4em;color: rgb(18, 18, 18);font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;font-size: medium;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">既然可以设置Redis最大占用内存大小,那么配置的内存就有用完的时候。那在内存用完的时候,还继续往Redis里面添加数据不就没内存可用了吗?</p> <p style="margin-top: 1.4em;margin-bottom: 1.4em;color: rgb(18, 18, 18);font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;font-size: medium;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">实际上Redis定义了几种策略用来处理这种情况:</p> <p style="margin-top: 1.4em;margin-bottom: 1.4em;color: rgb(18, 18, 18);font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;font-size: medium;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);"><span style="font-weight: 600;">noeviction(默认策略)</span>:对于写请求不再提供服务,直接返回错误(DEL请求和部分特殊请求除外)</p> <p style="margin-top: 1.4em;margin-bottom: 1.4em;color: rgb(18, 18, 18);font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;font-size: medium;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);"><span style="font-weight: 600;">allkeys-lru</span>:从所有key中使用LRU算法进行淘汰</p> <p style="margin-top: 1.4em;margin-bottom: 1.4em;color: rgb(18, 18, 18);font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;font-size: medium;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);"><span style="font-weight: 600;">volatile-lru</span>:从设置了过期时间的key中使用LRU算法进行淘汰</p> <p style="margin-top: 1.4em;margin-bottom: 1.4em;color: rgb(18, 18, 18);font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;font-size: medium;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);"><span style="font-weight: 600;">allkeys-random</span>:从所有key中随机淘汰数据</p> <p style="margin-top: 1.4em;margin-bottom: 1.4em;color: rgb(18, 18, 18);font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;font-size: medium;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);"><span style="font-weight: 600;">volatile-random</span>:从设置了过期时间的key中随机淘汰</p> <p style="margin-top: 1.4em;margin-bottom: 1.4em;color: rgb(18, 18, 18);font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;font-size: medium;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);"><span style="font-weight: 600;">volatile-ttl</span>:在设置了过期时间的key中,根据key的过期时间进行淘汰,越早过期的越优先被淘汰</p> <blockquote style="margin-top: 1.4em;margin-bottom: 1.4em;padding-left: 1em;color: rgb(100, 100, 100);border-left-color: rgb(211, 211, 211);font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;font-size: medium;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);"> 当使用 <span style="font-weight: 600;">volatile-lru</span>、 <span style="font-weight: 600;">volatile-random</span>、 <span style="font-weight: 600;">volatile-ttl</span>这三种策略时,如果没有key可以被淘汰,则和 <span style="font-weight: 600;">noeviction</span>一样返回错误 </blockquote> <h3 style="margin-top: 1.90909em;margin-bottom: 1.27273em;font-variant-numeric: inherit;font-weight: 600;font-stretch: inherit;font-size: 1.1em;line-height: 1.5;font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;clear: left;color: rgb(18, 18, 18);text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">如何获取及设置内存淘汰策略</h3> <p style="margin-top: 1.4em;margin-bottom: 1.4em;color: rgb(18, 18, 18);font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;font-size: medium;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">获取当前内存淘汰策略:</p> <pre style="padding: 0.88889em;font-size: 0.9em;word-break: normal;overflow-wrap: normal;overflow: auto;background: rgb(246, 246, 246);border-radius: 4px;"><code style="border-radius: 0px;font-family: Menlo, Monaco, Consolas, "Andale Mono", "lucida console", "Courier New", monospace;font-size: inherit;background-color: inherit;">127.0.0.1:6379> config get maxmemory-policy</code></pre> <p style="margin-top: -0.8em;margin-bottom: -0.8em;color: rgb(18, 18, 18);font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;font-size: medium;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);"><br></p> <p style="margin-top: 1.4em;margin-bottom: 1.4em;color: rgb(18, 18, 18);font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;font-size: medium;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">通过配置文件设置淘汰策略(修改redis.conf文件):</p> <pre style="padding: 0.88889em;font-size: 0.9em;word-break: normal;overflow-wrap: normal;overflow: auto;background: rgb(246, 246, 246);border-radius: 4px;"><code style="border-radius: 0px;font-family: Menlo, Monaco, Consolas, "Andale Mono", "lucida console", "Courier New", monospace;font-size: inherit;background-color: inherit;">maxmemory-policy allkeys-lru</code></pre> <p style="margin-top: 1.4em;margin-bottom: 1.4em;color: rgb(18, 18, 18);font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;font-size: medium;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">通过命令修改淘汰策略:</p> <pre style="padding: 0.88889em;font-size: 0.9em;word-break: normal;overflow-wrap: normal;overflow: auto;background: rgb(246, 246, 246);border-radius: 4px;"><code style="border-radius: 0px;font-family: Menlo, Monaco, Consolas, "Andale Mono", "lucida console", "Courier New", monospace;font-size: inherit;background-color: inherit;">127.0.0.1:6379> config set maxmemory-policy allkeys-lru`</code></pre> <h3 style="margin-top: 1.90909em;margin-bottom: 1.27273em;font-variant-numeric: inherit;font-weight: 600;font-stretch: inherit;font-size: 1.1em;line-height: 1.5;font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;clear: left;color: rgb(18, 18, 18);text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">LRU算法</h3> <h3 style="margin-top: 1.90909em;margin-bottom: 1.27273em;font-variant-numeric: inherit;font-weight: 600;font-stretch: inherit;font-size: 1.1em;line-height: 1.5;font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;clear: left;color: rgb(18, 18, 18);text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">什么是LRU?</h3> <p style="margin-top: 1.4em;margin-bottom: 1.4em;color: rgb(18, 18, 18);font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;font-size: medium;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">上面说到了Redis可使用最大内存使用完了,是可以使用LRU算法进行内存淘汰的,那么什么是LRU算法呢?</p> <blockquote style="margin-top: 1.4em;margin-bottom: 1.4em;padding-left: 1em;color: rgb(100, 100, 100);border-left-color: rgb(211, 211, 211);font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;font-size: medium;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);"> <span style="font-weight: 600;">LRU(Least Recently Used)</span>,即最近最少使用,是一种缓存置换算法。在使用内存作为缓存的时候,缓存的大小一般是固定的。当缓存被占满,这个时候继续往缓存里面添加数据,就需要淘汰一部分老的数据,释放内存空间用来存储新的数据。这个时候就可以使用LRU算法了。其核心思想是:如果一个数据在最近一段时间没有被用到,那么将来被使用到的可能性也很小,所以就可以被淘汰掉。 </blockquote> <h3 style="margin-top: 1.90909em;margin-bottom: 1.27273em;font-variant-numeric: inherit;font-weight: 600;font-stretch: inherit;font-size: 1.1em;line-height: 1.5;font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;clear: left;color: rgb(18, 18, 18);text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">LRU在Redis中的实现</h3> <h3 style="margin-top: 1.90909em;margin-bottom: 1.27273em;font-variant-numeric: inherit;font-weight: 600;font-stretch: inherit;font-size: 1.1em;line-height: 1.5;font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;clear: left;color: rgb(18, 18, 18);text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">近似LRU算法</h3> <p style="margin-top: 1.4em;margin-bottom: 1.4em;color: rgb(18, 18, 18);font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;font-size: medium;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">Redis使用的是近似LRU算法,它跟常规的LRU算法还不太一样。近似LRU算法通过随机采样法淘汰数据,每次随机出5(默认)个key,从里面淘汰掉最近最少使用的key。</p> <blockquote style="margin-top: 1.4em;margin-bottom: 1.4em;padding-left: 1em;color: rgb(100, 100, 100);border-left-color: rgb(211, 211, 211);font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;font-size: medium;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);"> 可以通过maxmemory-samples参数修改采样数量:例:maxmemory-samples 10 maxmenory-samples配置的越大,淘汰的结果越接近于严格的LRU算法 </blockquote> <p style="margin-top: 1.4em;margin-bottom: 1.4em;color: rgb(18, 18, 18);font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;font-size: medium;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">Redis为了实现近似LRU算法,给每个key增加了一个额外增加了一个24bit的字段,用来存储该key最后一次被访问的时间。</p> <h3 style="margin-top: 1.90909em;margin-bottom: 1.27273em;font-variant-numeric: inherit;font-weight: 600;font-stretch: inherit;font-size: 1.1em;line-height: 1.5;font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;clear: left;color: rgb(18, 18, 18);text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">Redis3.0对近似LRU的优化</h3> <p style="margin-top: 1.4em;margin-bottom: 1.4em;color: rgb(18, 18, 18);font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;font-size: medium;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">Redis3.0对近似LRU算法进行了一些优化。新算法会维护一个候选池(大小为16),池中的数据根据访问时间进行排序,第一次随机选取的key都会放入池中,随后每次随机选取的key只有在访问时间小于池中最小的时间才会放入池中,直到候选池被放满。当放满后,如果有新的key需要放入,则将池中最后访问时间最大(最近被访问)的移除。</p> <p style="margin-top: 1.4em;margin-bottom: 1.4em;color: rgb(18, 18, 18);font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;font-size: medium;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">当需要淘汰的时候,则直接从池中选取最近访问时间最小(最久没被访问)的key淘汰掉就行。</p> <h3 style="margin-top: 1.90909em;margin-bottom: 1.27273em;font-variant-numeric: inherit;font-weight: 600;font-stretch: inherit;font-size: 1.1em;line-height: 1.5;font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;clear: left;color: rgb(18, 18, 18);text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">LRU算法的对比</h3> <p style="margin-top: 1.4em;margin-bottom: 1.4em;color: rgb(18, 18, 18);font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;font-size: medium;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">我们可以通过一个实验对比各LRU算法的准确率,先往Redis里面添加一定数量的数据n,使Redis可用内存用完,再往Redis里面添加n/2的新数据,这个时候就需要淘汰掉一部分的数据,如果按照严格的LRU算法,应该淘汰掉的是最先加入的n/2的数据。生成如下各LRU算法的对比图</p> <figure data-size="normal" style="margin-top: 1.4em;margin-bottom: 1.4em;color: rgb(18, 18, 18);font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;font-size: medium;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);"> <img src="/upload/c552afb8334c63345a7b08dab51f8dbd.jpg" data-cropx1="0" data-cropx2="720" data-cropy1="0" data-cropy2="310.506512301013" data-ratio="0.4305555555555556" src="https://mmbiz.qpic.cn/mmbiz_jpg/hUzEz6BmcaqicHb61lpHuh94EekcAowzGBia8pOjHFicwnWNCdSbceJ5cMacsWibNBOgEY4jxoc1LHUK7H00XwT4DQ/640?wx_fmt=jpeg" data-type="jpeg" data-w="720" style="display: block;margin-right: auto;margin-left: auto;cursor: zoom-in;background-color: transparent;animation: 0.5s ease-in 0s 1 normal none running fxRichTextFadeIn;width: 578px;height: 249px;"> </figure> <p style="margin-top: -0.8em;margin-bottom: -0.8em;color: rgb(18, 18, 18);font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;font-size: medium;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);"><br></p> <p style="margin-top: 1.4em;margin-bottom: 1.4em;color: rgb(18, 18, 18);font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;font-size: medium;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">你可以看到图中有三种不同颜色的点:</p> <ul style="margin-top: 1.4em;margin-bottom: 1.4em;display: table;color: rgb(18, 18, 18);font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;font-size: medium;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);" class="list-paddingleft-2"> <li style="list-style: none;display: table-row;"><p>浅灰色是被淘汰的数据</p></li> <li style="list-style: none;display: table-row;"><p>灰色是没有被淘汰掉的老数据</p></li> <li style="list-style: none;display: table-row;"><p>绿色是新加入的数据</p></li> </ul> <p style="margin-top: 1.4em;margin-bottom: 1.4em;color: rgb(18, 18, 18);font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;font-size: medium;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">我们能看到Redis3.0采样数是10生成的图最接近于严格的LRU。而同样使用5个采样数,Redis3.0也要优于Redis2.8。</p> <h3 style="margin-top: 1.90909em;margin-bottom: 1.27273em;font-variant-numeric: inherit;font-weight: 600;font-stretch: inherit;font-size: 1.1em;line-height: 1.5;font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;clear: left;color: rgb(18, 18, 18);text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">LFU算法</h3> <p style="margin-top: 1.4em;margin-bottom: 1.4em;color: rgb(18, 18, 18);font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;font-size: medium;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">LFU算法是Redis4.0里面新加的一种淘汰策略。它的全称是<span style="font-weight: 600;">Least Frequently Used</span>,它的核心思想是根据key的最近被访问的频率进行淘汰,很少被访问的优先被淘汰,被访问的多的则被留下来。</p> <p style="margin-top: 1.4em;margin-bottom: 1.4em;color: rgb(18, 18, 18);font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;font-size: medium;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">LFU算法能更好的表示一个key被访问的热度。假如你使用的是LRU算法,一个key很久没有被访问到,只刚刚是偶尔被访问了一次,那么它就被认为是热点数据,不会被淘汰,而有些key将来是很有可能被访问到的则被淘汰了。如果使用LFU算法则不会出现这种情况,因为使用一次并不会使一个key成为热点数据。</p> <p style="margin-top: 1.4em;margin-bottom: 1.4em;color: rgb(18, 18, 18);font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;font-size: medium;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">LFU一共有两种策略:</p> <p style="margin-top: 1.4em;margin-bottom: 1.4em;color: rgb(18, 18, 18);font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;font-size: medium;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">volatile-lfu:在设置了过期时间的key中使用LFU算法淘汰key</p> <p style="margin-top: 1.4em;margin-bottom: 1.4em;color: rgb(18, 18, 18);font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;font-size: medium;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">allkeys-lfu:在所有的key中使用LFU算法淘汰数据</p> <blockquote style="margin-top: 1.4em;margin-bottom: 1.4em;padding-left: 1em;color: rgb(100, 100, 100);border-left-color: rgb(211, 211, 211);font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;font-size: medium;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);"> 设置使用这两种淘汰策略跟前面讲的一样,不过要注意的一点是这两周策略只能在Redis4.0及以上设置,如果在Redis4.0以下设置会报错 </blockquote> <h3 style="margin-top: 1.90909em;margin-bottom: 1.27273em;font-variant-numeric: inherit;font-weight: 600;font-stretch: inherit;font-size: 1.1em;line-height: 1.5;font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;clear: left;color: rgb(18, 18, 18);text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">问题</h3> <p style="margin-top: 1.4em;color: rgb(18, 18, 18);font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;font-size: medium;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">最后留一个小问题,可能有的人注意到了,文中并没有解释为什么Redis使用近似LRU算法而不使用准确的LRU算法,可以一起讨论学习。</p> </header> <section powered-by="xiumi.us" style="max-width: 100%;font-size: 16px;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: center;color: rgb(62, 71, 83);font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <section style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <section style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <section style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <section powered-by="xiumi.us" style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <section style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <p style="margin-right: 16px;margin-left: 16px;max-width: 100%;min-height: 1em;letter-spacing: 1.5px;line-height: 1.5em;font-family: -apple-system-font, BlinkMacSystemFont, Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;color: rgb(77, 168, 238);box-sizing: border-box !important;overflow-wrap: break-word !important;"><strong style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 12px;letter-spacing: 1px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><strong style="max-width: 100%;font-size: 17px;letter-spacing: 0.544px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 12px;box-sizing: border-box !important;overflow-wrap: break-word !important;">— 本文结束 —</span></strong></span></strong></span><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></p> <p style="margin-right: 16px;margin-left: 16px;max-width: 100%;min-height: 1em;letter-spacing: 1.5px;line-height: 1.5em;font-family: -apple-system-font, BlinkMacSystemFont, Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></p> <section data-mpa-template="t" mpa-from-tpl="t" style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <section data-id="93709" mpa-from-tpl="t" style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <section mpa-from-tpl="t" style="padding: 5px;max-width: 100%;border-style: solid;border-width: 2px;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <section mpa-from-tpl="t" style="padding: 15px;max-width: 100%;border-style: dashed;border-width: 1px;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <section mpa-from-tpl="t" style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <span data-role="width" data-width="80%" style="max-width: 100%;display: inline-block;width: 425.215px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><img border="0" class="__bg_gif" data-ratio="0.08658008658008658" data-type="gif" data-w="462" data-width="80%" height="" title="" width="80%" src="/upload/b0b0d65a8077fe5fc54ccd945913d458.png" style="box-sizing: border-box !important;overflow-wrap: break-word !important;visibility: visible !important;width: 340.156px !important;"></span> </section> <p style="margin-top: 5px;margin-bottom: 5px;padding-right: 0em;padding-left: 0em;max-width: 100%;min-height: 1em;text-align: justify;letter-spacing: 1.5px;line-height: normal;color: rgb(136, 136, 136);font-size: 13px;box-sizing: border-box !important;overflow-wrap: break-word !important;">● <a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzA5NDg3MjAwMQ==&mid=2457103446&idx=1&sn=0d0c0cb83235675963be01cb7b8ddb7b&chksm=87c8c4f8b0bf4dee91ab4a8041363afc0839df2dbc219e2c0938ed2e53d13af4a966121314f4&scene=21#wechat_redirect" textvalue="漫谈设计模式在 Spring 框架中的良好实践" data-itemshowtype="0" tab="innerlink" data-linktype="2" hasload="1" style="color: var(--weui-LINK);-webkit-tap-highlight-color: rgba(0, 0, 0, 0);cursor: pointer;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">漫谈设计模式在 Spring 框架中的良好实践</a></p> <p style="margin-top: 5px;margin-bottom: 5px;padding-right: 0em;padding-left: 0em;max-width: 100%;min-height: 1em;text-align: justify;letter-spacing: 1.5px;line-height: normal;color: rgb(136, 136, 136);font-size: 13px;box-sizing: border-box !important;overflow-wrap: break-word !important;">● <a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzA5NDg3MjAwMQ==&mid=2457103280&idx=1&sn=f3bd921a2f88a9a3440c0ff1e03d1bd9&chksm=87c8c31eb0bf4a0820a572626141cfb1fc87ea1c7072a16f61992d67d21d9b61b556de2d6cd7&scene=21#wechat_redirect" textvalue="颠覆微服务认知:深入思考微服务的七个主流观点" data-itemshowtype="11" tab="innerlink" data-linktype="2" hasload="1" style="color: var(--weui-LINK);-webkit-tap-highlight-color: rgba(0, 0, 0, 0);cursor: pointer;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">颠覆微服务认知:</a><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzA5NDg3MjAwMQ==&mid=2457103280&idx=1&sn=f3bd921a2f88a9a3440c0ff1e03d1bd9&chksm=87c8c31eb0bf4a0820a572626141cfb1fc87ea1c7072a16f61992d67d21d9b61b556de2d6cd7&scene=21#wechat_redirect" textvalue="颠覆微服务认知:深入思考微服务的七个主流观点" data-itemshowtype="11" tab="innerlink" data-linktype="2" hasload="1" style="color: var(--weui-LINK);-webkit-tap-highlight-color: rgba(0, 0, 0, 0);cursor: pointer;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">深入思考微服务的七个主流观点</a><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></p> <p style="margin-top: 5px;margin-bottom: 5px;padding-right: 0em;padding-left: 0em;max-width: 100%;min-height: 1em;text-align: justify;letter-spacing: 1.5px;line-height: normal;color: rgb(136, 136, 136);font-size: 13px;box-sizing: border-box !important;overflow-wrap: break-word !important;">● <a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzA5NDg3MjAwMQ==&mid=2457103129&idx=1&sn=3e0386d5f6f3b706e6bd72195648e34e&chksm=87c8c3b7b0bf4aa1530354a3b1507b33c5033db70e4c61328e9ed68118e24212a36d763671d8&scene=21#wechat_redirect" textvalue="人人都是 API 设计者" data-itemshowtype="0" tab="innerlink" data-linktype="2" hasload="1" style="color: var(--weui-LINK);-webkit-tap-highlight-color: rgba(0, 0, 0, 0);cursor: pointer;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">人人都是 API 设计者</a></p> <p style="margin-top: 5px;margin-bottom: 5px;padding-right: 0em;padding-left: 0em;max-width: 100%;min-height: 1em;text-align: justify;letter-spacing: 1.5px;line-height: normal;color: rgb(136, 136, 136);font-size: 13px;box-sizing: border-box !important;overflow-wrap: break-word !important;">● <a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzA5NDg3MjAwMQ==&mid=2457103538&idx=1&sn=9261bb2b742fd41168889738e0377a9c&chksm=87c8c41cb0bf4d0a5401fac49320faebfc4ac5ad7711d39758ecb0fd9df43354d19aa5aa57e3&scene=21#wechat_redirect" textvalue="一文讲透微服务下如何保证事务的一致性" data-itemshowtype="0" tab="innerlink" data-linktype="2" hasload="1" style="color: var(--weui-LINK);-webkit-tap-highlight-color: rgba(0, 0, 0, 0);cursor: pointer;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">一文讲透微服务下如何保证事务的一致性</a><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></p> <p style="margin-top: 5px;margin-bottom: 5px;padding-right: 0em;padding-left: 0em;max-width: 100%;min-height: 1em;text-align: justify;letter-spacing: 1.5px;line-height: normal;color: rgb(136, 136, 136);font-size: 13px;box-sizing: border-box !important;overflow-wrap: break-word !important;">● <a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzA5NDg3MjAwMQ==&mid=2457103584&idx=1&sn=007226d602709eb3c840a0539dae678b&chksm=87c8c44eb0bf4d58e9aaba3221c0d9f61556f4a199691b428dd322231ab450023e748cfc620a&scene=21#wechat_redirect" textvalue="要黑盒测试微服务内部服务间调用,我该如何实现?" data-itemshowtype="0" tab="innerlink" data-linktype="2" hasload="1" style="color: var(--weui-LINK);-webkit-tap-highlight-color: rgba(0, 0, 0, 0);cursor: pointer;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">要黑盒测试微服务内部服务间调用,我该如何实现?</a><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></p> </section> </section> </section> </section> <p style="max-width: 100%;min-height: 1em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br mpa-from-tpl="t" style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></p> </section> </section> </section> </section> </section> </section> <section powered-by="xiumi.us" style="max-width: 100%;font-size: 16px;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: center;color: rgb(62, 71, 83);font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <section style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <section style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <section style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <section powered-by="xiumi.us" style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <section style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <p style="max-width: 100%;min-height: 1em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><img data-ratio="0.3708738" data-type="png" data-w="515" src="/upload/328ca60e65e37255ffc9d00bfba58c3c.png" style="vertical-align: middle;box-sizing: border-box !important;overflow-wrap: break-word !important;visibility: visible !important;width: 515px !important;"></p> <p style="margin-right: 16px;margin-left: 16px;max-width: 100%;min-height: 1em;letter-spacing: 1.5px;line-height: 1.5em;font-family: -apple-system-font, BlinkMacSystemFont, Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></p> <section style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <section powered-by="xiumi.us" style="margin-top: 10px;margin-bottom: 10px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <section style="max-width: 100%;display: inline-block;width: 574px;vertical-align: top;border-style: solid;border-width: 1px;border-radius: 0px;border-color: rgb(225, 238, 226);background-color: rgba(191, 224, 216, 0.58);box-sizing: border-box !important;overflow-wrap: break-word !important;"> <section powered-by="xiumi.us" style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <section style="padding: 10px;max-width: 100%;display: inline-block;width: 572px;vertical-align: top;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <section powered-by="xiumi.us" style="max-width: 100%;font-size: 15px;color: rgb(46, 101, 91);line-height: 1.8;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <p style="max-width: 100%;min-height: 1em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 12px;box-sizing: border-box !important;overflow-wrap: break-word !important;">关注我,回复 「加群」 加入各种主题讨论群。</span></p> </section> </section> </section> </section> </section> <section powered-by="xiumi.us" style="margin-top: 10px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <section style="max-width: 100%;background-color: rgb(147, 195, 186);height: 2px;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"> </section> </section> </section> </section> </section> </section> </section> </section> </section> <section powered-by="xiumi.us" style="max-width: 100%;font-size: 16px;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: center;color: rgb(62, 71, 83);font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <section style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <section style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <p style="max-width: 100%;min-height: 1em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></p> <p style="margin-right: 16px;margin-left: 16px;max-width: 100%;min-height: 1em;letter-spacing: 1.5px;line-height: 1.5em;font-family: -apple-system-font, BlinkMacSystemFont, Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"><strong style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 12px;letter-spacing: 1px;color: rgb(0, 0, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">对「服务端思维」有期待,请在文末点个<span style="max-width: 100%;color: rgb(198, 19, 25);box-sizing: border-box !important;overflow-wrap: break-word !important;">在看</span></span></strong></p> <p style="margin-right: 16px;margin-left: 16px;max-width: 100%;min-height: 1em;letter-spacing: 1.5px;line-height: 1.5em;font-family: -apple-system-font, BlinkMacSystemFont, Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"><strong style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 12px;letter-spacing: 1px;color: rgb(0, 0, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">喜欢这篇文章,欢迎<span style="max-width: 100%;color: rgb(198, 19, 25);box-sizing: border-box !important;overflow-wrap: break-word !important;">转发、分享</span>朋友圈</span></strong></p> </section> </section> </section> <p style="max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(63, 63, 63);font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif;font-size: 14px;text-align: center;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></p> <section data-role="outer" label="Powered by 135editor.com" style="max-width: 100%;font-size: 16px;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(63, 63, 63);font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif;text-align: center;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <section data-role="outer" label="Powered by 135editor.com" style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <section data-tools="135编辑器" data-id="94783" style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <section style="max-width: 100%;display: flex;justify-content: flex-end;align-items: center;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <section style="max-width: 100%;width: 20px;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <section style="max-width: 100%;width: 20px;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <img data-ratio="1.037037037037037" data-type="png" data-w="27" data-width="100%" src="/upload/6087772642bee9a4b8104517c36c9aa7.png" style="display: block;box-sizing: border-box !important;overflow-wrap: break-word !important;visibility: visible !important;width: 20px !important;"> </section> </section> <section style="max-width: 100%;display: inline-block;text-align: right;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <section data-brushtype="text" style="margin-bottom: -15px;max-width: 100%;letter-spacing: 2px;transform: rotate(0deg);box-sizing: border-box !important;overflow-wrap: break-word !important;"> 在看点这里 </section> </section> <section style="max-width: 100%;width: 22px;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <section style="margin-top: 15px;max-width: 100%;width: 22px;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <img class="__bg_gif" data-ratio="1" data-type="gif" data-w="100" data-width="100%" src="/upload/8b34c0e8ddcf33f56770ae9f44c95ce1.png" style="display: block;box-sizing: border-box !important;overflow-wrap: break-word !important;visibility: visible !important;width: 22px !important;"> </section> </section> </section> </section> </section> </section>
作者:微信小助手
<p style="text-align: center;"><span style="font-size: 14px;letter-spacing: 0.5440000295639038px;text-align: center;max-width: 100%;color: rgb(255, 41, 65);line-height: 22.4px;">(给</span><span style="font-size: 14px;letter-spacing: 0.5440000295639038px;text-align: center;max-width: 100%;line-height: 22.4px;color: rgb(0, 128, 255);">ImportNew</span><span style="font-size: 14px;letter-spacing: 0.5440000295639038px;text-align: center;max-width: 100%;color: rgb(255, 41, 65);line-height: 22.4px;">加星标,提高Java技能)</span></p> <blockquote> <p style="letter-spacing: 0.5440000295639038px;white-space: normal;background-color: rgb(255, 255, 255);max-width: 100%;min-height: 1em;text-align: left;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 14px;box-sizing: border-box !important;overflow-wrap: break-word !important;">转自:<span style="color: rgb(154, 154, 154);font-size: 14px;letter-spacing: 0.544px;text-align: left;background-color: rgb(255, 255, 255);">陶章</span><span style="color: rgb(154, 154, 154);font-size: 14px;letter-spacing: 0.544px;text-align: left;background-color: rgb(255, 255, 255);">好</span></span></p> <p style="letter-spacing: 0.5440000295639038px;white-space: normal;background-color: rgb(255, 255, 255);max-width: 100%;min-height: 1em;text-align: left;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 14px;letter-spacing: 0.544px;">链接:</span><span style="font-size: 14px;letter-spacing: 0.544px;">https://juejin.im/post/5d026212f265da1b8608828b</span></p> </blockquote> <p style="text-align: left;"><span style="font-size: 15px;">Idea是Java开发利器,SpringBoot是Java生态中最流行的微服务框架,docker是时下最火的容器技术,那么它们结合在一起会产生什么化学反应呢?</span><br></p> <p style="text-align: left;"><span style="font-size: 16px;font-family: Optima-Regular, PingFangTC-light;"><br></span></p> <h2 data-id="heading-0" style="text-align: left;"><span style="color: rgb(171, 25, 66);"><strong><span style="color: rgb(171, 25, 66);font-size: 15px;text-align: left;">一、开发前准备</span></strong></span></h2> <p><strong><span style="font-size: 16px;font-family: Optima-Regular, PingFangTC-light;"><br></span></strong></p> <h4 data-id="heading-1" style="text-align: left;"><span style="font-size: 15px;">1. Docker的安装可以参考https://docs.docker.com/install/</span></h4> <h4 data-id="heading-2" style="text-align: left;"><br></h4> <h4 data-id="heading-2" style="text-align: left;"><span style="font-size: 15px;">2. 配置docker远程连接端口</span></h4> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="nginx"><code><span class="code-snippet_outer"> <span class="code-snippet__attribute">vi</span> /usr/lib/systemd/system/docker.service</span></code></pre> </section> <p style="text-align: left;"><span style="font-size: 15px;"><br>找到 ExecStart,在最后面添加 -H tcp://0.0.0.0:2375,如下图所示</span></p> <p><br></p> <figure style="text-align: left;"> <br> </figure> <figure style="text-align: center;"> <img data-height="284" data-ratio="0.37270341207349084" src="/upload/b57961482942917e3ba0845ef85cede0.png" data-type="other" data-w="762" data-width="762"> </figure> <p><br></p> <p><br></p> <h4 data-id="heading-3" style="text-align: left;"><span style="font-size: 15px;">3. 重启docker</span></h4> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="properties"><code><span class="code-snippet_outer"> <span class="code-snippet__attr">systemctl</span> <span class="code-snippet__string">daemon-reload</span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__attr">systemctl</span> <span class="code-snippet__string">start docker</span></span></code></pre> </section> <pre style="text-align: left;"><br></pre> <h4 data-id="heading-4" style="text-align: left;"><span style="font-size: 15px;">4. 开放端口</span></h4> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="cs"><code><span class="code-snippet_outer">firewall-cmd --zone=<span class="code-snippet__keyword">public</span> --<span class="code-snippet__keyword">add</span>-port=<span class="code-snippet__number">2375</span>/tcp --permanent</span></code></pre> </section> <pre style="text-align: left;"><span style="font-size: 16px;font-family: Optima-Regular, PingFangTC-light;"></span><br></pre> <h4 data-id="heading-5" style="text-align: left;"><span style="font-size: 15px;">5. Idea安装插件,重启</span></h4> <p style="text-align: left;"><br></p> <figure style="text-align: center;"> <img data-height="722" data-ratio="0.5846153846153846" src="/upload/4c0fe35d9247f0afaa9cce322e59f99e.png" data-type="other" data-w="1235" data-width="1235"> </figure> <p><br></p> <h4 data-id="heading-6" style="text-align: left;">6. 连接远程docker</h4> <p><span style="font-size: 16px;font-family: Optima-Regular, PingFangTC-light;background-color: rgb(255, 218, 169);"><br></span></p> <h4 data-id="heading-7" style="text-align: left;"><span style="font-size: 16px;font-family: Optima-Regular, PingFangTC-light;"> (1) 编辑配置</span></h4> <figure style="text-align: center;"> <img data-height="180" data-ratio="0.40089086859688194" src="/upload/888629629d3e852d787e8d7ddae186ad.png" data-type="other" data-w="449" data-width="449"> </figure> <h4 data-id="heading-8" style="text-align: left;"><span style="font-size: 16px;font-family: Optima-Regular, PingFangTC-light;"> </span></h4> <h4 data-id="heading-8" style="text-align: left;"><span style="font-size: 16px;font-family: Optima-Regular, PingFangTC-light;"> (2) 填远程docker地址</span></h4> <figure style="text-align: center;"> <img data-height="545" data-ratio="1.1822125813449025" src="/upload/c13714005b1bb4428ce56dc4c4384afb.png" data-type="other" data-w="461" data-width="461"> </figure> <h4 data-id="heading-9" style="text-align: left;"><br></h4> <h4 data-id="heading-9" style="text-align: left;"><span style="font-size: 16px;font-family: Optima-Regular, PingFangTC-light;"> (3) 连接成功,会列出远程docker容器和镜像</span></h4> <figure style="text-align: left;"> <img data-height="215" data-ratio="0.20692974013474494" src="/upload/144c00e4dd0a948e9d3891deb4f68f21.png" data-type="other" data-w="1039" data-width="1039"> </figure> <p><br></p> <h2 data-id="heading-10" style="text-align: left;"><span style="color: rgb(171, 25, 66);"><strong><span style="color: rgb(171, 25, 66);font-size: 15px;text-align: left;">二、新建项目</span></strong></span><span style="font-size: 16px;font-family: Optima-Regular, PingFangTC-light;"></span></h2> <p style="text-align: left;"><br></p> <h4 data-id="heading-11" style="text-align: left;">1. 创建springboot项目</h4> <p><span style="font-size: 16px;font-family: Optima-Regular, PingFangTC-light;background-color: rgb(255, 218, 169);"><br></span></p> <p style="text-align: left;"><span style="font-size: 16px;font-family: Optima-Regular, PingFangTC-light;">项目结构图</span></p> <p><br></p> <figure style="text-align: center;"> <img data-height="384" data-ratio="1.0971428571428572" src="/upload/47340598350e7a9fb0c1cc8f2aa1ce0d.png" data-type="other" data-w="350" data-width="350"> </figure> <p><br></p> <h4 data-id="heading-12" style="text-align: left;">(1) 配置pom文件</h4> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="xml"><code><span class="code-snippet_outer"><span class="code-snippet__meta"><?xml version="1.0" encoding="UTF-8"?></span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__tag"><<span class="code-snippet__name">project</span> <span class="code-snippet__attr">xmlns</span>=<span class="code-snippet__string">"http://maven.apache.org/POM/4.0.0"</span></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__attr">xmlns:xsi</span>=<span class="code-snippet__string">"http://www.w3.org/2001/XMLSchema-instance"</span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__attr">xsi:schemaLocation</span>=<span class="code-snippet__string">"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"</span>></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">modelVersion</span>></span>4.0.0<span class="code-snippet__tag"></<span class="code-snippet__name">modelVersion</span>></span></span></code><code><span class="code-snippet_outer"><br></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">groupId</span>></span>docker-demo<span class="code-snippet__tag"></<span class="code-snippet__name">groupId</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">artifactId</span>></span>com.demo<span class="code-snippet__tag"></<span class="code-snippet__name">artifactId</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">version</span>></span>1.0-SNAPSHOT<span class="code-snippet__tag"></<span class="code-snippet__name">version</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">parent</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">groupId</span>></span>org.springframework.boot<span class="code-snippet__tag"></<span class="code-snippet__name">groupId</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">artifactId</span>></span>spring-boot-starter-parent<span class="code-snippet__tag"></<span class="code-snippet__name">artifactId</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">version</span>></span>2.0.2.RELEASE<span class="code-snippet__tag"></<span class="code-snippet__name">version</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">relativePath</span> /></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"></<span class="code-snippet__name">parent</span>></span></span></code><code><span class="code-snippet_outer"><br></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">properties</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">project.build.sourceEncoding</span>></span>UTF-8<span class="code-snippet__tag"></<span class="code-snippet__name">project.build.sourceEncoding</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">project.reporting.outputEncoding</span>></span>UTF-8<span class="code-snippet__tag"></<span class="code-snippet__name">project.reporting.outputEncoding</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">docker.image.prefix</span>></span>com.demo<span class="code-snippet__tag"></<span class="code-snippet__name">docker.image.prefix</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">java.version</span>></span>1.8<span class="code-snippet__tag"></<span class="code-snippet__name">java.version</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"></<span class="code-snippet__name">properties</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">build</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">plugins</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">plugin</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">groupId</span>></span>org.springframework.boot<span class="code-snippet__tag"></<span class="code-snippet__name">groupId</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">artifactId</span>></span>spring-boot-maven-plugin<span class="code-snippet__tag"></<span class="code-snippet__name">artifactId</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"></<span class="code-snippet__name">plugin</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">plugin</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">groupId</span>></span>com.spotify<span class="code-snippet__tag"></<span class="code-snippet__name">groupId</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">artifactId</span>></span>docker-maven-plugin<span class="code-snippet__tag"></<span class="code-snippet__name">artifactId</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">version</span>></span>1.0.0<span class="code-snippet__tag"></<span class="code-snippet__name">version</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">configuration</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">dockerDirectory</span>></span>src/main/docker<span class="code-snippet__tag"></<span class="code-snippet__name">dockerDirectory</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">resources</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">resource</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">targetPath</span>></span>/<span class="code-snippet__tag"></<span class="code-snippet__name">targetPath</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">directory</span>></span>${project.build.directory}<span class="code-snippet__tag"></<span class="code-snippet__name">directory</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">include</span>></span>${project.build.finalName}.jar<span class="code-snippet__tag"></<span class="code-snippet__name">include</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"></<span class="code-snippet__name">resource</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"></<span class="code-snippet__name">resources</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"></<span class="code-snippet__name">configuration</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"></<span class="code-snippet__name">plugin</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">plugin</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">artifactId</span>></span>maven-antrun-plugin<span class="code-snippet__tag"></<span class="code-snippet__name">artifactId</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">executions</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">execution</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">phase</span>></span>package<span class="code-snippet__tag"></<span class="code-snippet__name">phase</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">configuration</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">tasks</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">copy</span> <span class="code-snippet__attr">todir</span>=<span class="code-snippet__string">"src/main/docker"</span> <span class="code-snippet__attr">file</span>=<span class="code-snippet__string">"target/${project.artifactId}-${project.version}.${project.packaging}"</span>></span><span class="code-snippet__tag"></<span class="code-snippet__name">copy</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"></<span class="code-snippet__name">tasks</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"></<span class="code-snippet__name">configuration</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">goals</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">goal</span>></span>run<span class="code-snippet__tag"></<span class="code-snippet__name">goal</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"></<span class="code-snippet__name">goals</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"></<span class="code-snippet__name">execution</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"></<span class="code-snippet__name">executions</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"></<span class="code-snippet__name">plugin</span>></span></span></code><code><span class="code-snippet_outer"><br></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"></<span class="code-snippet__name">plugins</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"></<span class="code-snippet__name">build</span>></span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__tag"><<span class="code-snippet__name">dependencies</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">dependency</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">groupId</span>></span>org.springframework.boot<span class="code-snippet__tag"></<span class="code-snippet__name">groupId</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">artifactId</span>></span>spring-boot-starter-web<span class="code-snippet__tag"></<span class="code-snippet__name">artifactId</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"></<span class="code-snippet__name">dependency</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">dependency</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">groupId</span>></span>org.springframework.boot<span class="code-snippet__tag"></<span class="code-snippet__name">groupId</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">artifactId</span>></span>spring-boot-starter-test<span class="code-snippet__tag"></<span class="code-snippet__name">artifactId</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">scope</span>></span>test<span class="code-snippet__tag"></<span class="code-snippet__name">scope</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"></<span class="code-snippet__name">dependency</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">dependency</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">groupId</span>></span>log4j<span class="code-snippet__tag"></<span class="code-snippet__name">groupId</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">artifactId</span>></span>log4j<span class="code-snippet__tag"></<span class="code-snippet__name">artifactId</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">version</span>></span>1.2.17<span class="code-snippet__tag"></<span class="code-snippet__name">version</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"></<span class="code-snippet__name">dependency</span>></span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__tag"></<span class="code-snippet__name">dependencies</span>></span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__tag"></<span class="code-snippet__name">project</span>></span></span></code></pre> </section> <pre style="text-align: left;"><br></pre> <h4 data-id="heading-13" style="text-align: left;">(2) 在src/main目录下创建docker目录,并创建Dockerfile文件</h4> <p><span style="font-size: 16px;font-family: Optima-Regular, PingFangTC-light;background-color: rgb(255, 218, 169);"><br></span></p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="nginx"><code><span class="code-snippet_outer"><span class="code-snippet__attribute">FROM</span> openjdk:<span class="code-snippet__number">8</span>-jdk-alpine</span></code><code><span class="code-snippet_outer">ADD <span class="code-snippet__regexp">*.jar</span> app.jar</span></code><code><span class="code-snippet_outer">ENTRYPOINT [<span class="code-snippet__string">"java"</span>,<span class="code-snippet__string">"-Djava.security.egd=file:/dev/./urandom"</span>,<span class="code-snippet__string">"-jar"</span>,<span class="code-snippet__string">"/app.jar"</span>]</span></code></pre> </section> <pre style="text-align: left;"><br></pre> <h4 data-id="heading-14" style="text-align: left;">(3) 在resource目录下创建application.properties文件</h4> <p><span style="font-size: 16px;font-family: Optima-Regular, PingFangTC-light;background-color: rgb(255, 218, 169);"><br></span></p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="javascript"><code><span class="code-snippet_outer">logging.config=classpath:logback.xml</span></code><code><span class="code-snippet_outer">logging.path=<span class="code-snippet__regexp">/home/</span>developer/app/logs/</span></code><code><span class="code-snippet_outer">server.port=<span class="code-snippet__number">8990</span></span></code></pre> </section> <pre style="text-align: left;"><br></pre> <h4 data-id="heading-15" style="text-align: left;">(4) 创建DockerApplication文件</h4> <p><span style="font-size: 16px;font-family: Optima-Regular, PingFangTC-light;background-color: rgb(255, 218, 169);"><br></span></p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="java"><code><span class="code-snippet_outer"><span class="code-snippet__meta">@SpringBootApplication</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">public</span> <span class="code-snippet__class"><span class="code-snippet__keyword">class</span> <span class="code-snippet__title">DockerApplication</span> </span>{</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">static</span> <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">main</span><span class="code-snippet__params">(String[] args)</span> </span>{</span></code><code><span class="code-snippet_outer"> SpringApplication.run(DockerApplication.class, args);</span></code><code><span class="code-snippet_outer"> }</span></code><code><span class="code-snippet_outer">}</span></code></pre> </section> <pre style="text-align: left;"><br></pre> <h4 data-id="heading-16" style="text-align: left;">(5) 创建DockerController文件</h4> <p><span style="font-size: 16px;font-family: Optima-Regular, PingFangTC-light;background-color: rgb(255, 218, 169);"><br></span></p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="kotlin"><code><span class="code-snippet_outer"><span class="code-snippet__meta">@RestController</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">public</span> <span class="code-snippet__class"><span class="code-snippet__keyword">class</span> <span class="code-snippet__title">DockerController</span> </span>{</span></code><code><span class="code-snippet_outer"> static Log log = LogFactory.getLog(DockerController.<span class="code-snippet__keyword">class</span>);</span></code><code><span class="code-snippet_outer"><br></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__meta">@RequestMapping(<span class="code-snippet__meta-string">"/"</span>)</span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__keyword">public</span> String index() {</span></code><code><span class="code-snippet_outer"> log.info(<span class="code-snippet__string">"Hello Docker!"</span>);</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__keyword">return</span> <span class="code-snippet__string">"Hello Docker!"</span>;</span></code><code><span class="code-snippet_outer"> }</span></code><code><span class="code-snippet_outer">}</span></code></pre> </section> <pre style="text-align: left;"><br></pre> <h4 data-id="heading-17" style="text-align: left;">(6) 增加配置</h4> <p style="text-align: left;"><br></p> <figure style="text-align: center;"> <img data-height="53" data-ratio="0.27040816326530615" src="/upload/6a9937860b26f31c0139b5f84fd6733e.png" data-type="other" data-w="196" data-width="196"> </figure> <p><br></p> <figure style="text-align: center;"> <img data-height="358" data-ratio="0.7396694214876033" src="/upload/b5793e575daf529a46fe9ae0a6a3b4b8.png" data-type="other" data-w="484" data-width="484"> </figure> <p><br></p> <figure style="text-align: left;"> <img data-height="858" data-ratio="0.7907834101382488" src="/upload/580905fb089fe7268fbc534c0934877.png" data-type="other" data-w="1085" data-width="1085"> </figure> <p><br></p> <p style="text-align: left;"><strong><span style="font-family: Optima-Regular, PingFangTC-light;font-size: 16px;">命令解释</span></strong><br></p> <p style="text-align: left;"><br></p> <p style="text-align: left;"><span style="font-size: 16px;font-family: Optima-Regular, PingFangTC-light;">Image tag : 指定镜像名称和tag,镜像名称为 docker-demo,tag为1.1<br>Bind ports : 绑定宿主机端口到容器内部端口。格式为[宿主机端口]:[容器内</span><span style="font-family: Optima-Regular, PingFangTC-light;font-size: 16px;">部端口]</span></p> <p style="text-align: left;"><span style="font-size: 16px;font-family: Optima-Regular, PingFangTC-light;">Bind mounts : 将宿主机目录挂到到容器内部目录中。格式为[宿主机目录]:[容器内部目录]。这个springboot项目会将日志打印在容器 </span></p> <p style="text-align: left;"><span style="font-size: 16px;font-family: Optima-Regular, PingFangTC-light;">/home/developer/app/logs/ 目录下,将宿主机目录挂载到容器内部目录后,那么日志就会持久化容器外部的宿主机目录中。</span></p> <p style="text-align: left;"><span style="font-size: 16px;font-family: Optima-Regular, PingFangTC-light;"><br></span></p> <h4 data-id="heading-18" style="text-align: left;">(7) Maven打包</h4> <p><span style="font-size: 16px;font-family: Optima-Regular, PingFangTC-light;background-color: rgb(255, 218, 169);"><br></span></p> <figure style="text-align: center;"> <img data-height="474" data-ratio="1.3581661891117478" src="/upload/3e1d71e00086603d885cb6c7db8e3184.png" data-type="other" data-w="349" data-width="349"> </figure> <p><br></p> <h4 data-id="heading-19" style="text-align: left;">(8) 运行</h4> <p style="text-align: left;"><br></p> <figure style="text-align: center;"> <img data-height="48" data-ratio="0.17454545454545456" src="/upload/4c21ad1e01b5a8ac8f7a163e51d8f7e4.png" data-type="other" data-w="275" data-width="275"> </figure> <figure style="text-align: center;"> <img data-height="672" data-ratio="0.525" src="/upload/9fe010456406cb97ac5736ef8c9f915c.png" data-type="other" data-w="1280" data-width="1280"> </figure> <p style="text-align: left;"><br></p> <p style="text-align: left;"><span style="font-size: 16px;font-family: Optima-Regular, PingFangTC-light;">先pull基础镜像,然后再打包镜像,并将镜像部署到远程docker运行</span></p> <p style="text-align: left;"><span style="font-size: 16px;font-family: Optima-Regular, PingFangTC-light;"><br></span></p> <figure style="text-align: center;"> <img data-height="663" data-ratio="0.51875" src="/upload/b5bcc1b0c2c7d255d42b9e8c83d5a113.png" data-type="other" data-w="1280" data-width="1280"> </figure> <p style="text-align: left;"><span style="font-size: 16px;font-family: Optima-Regular, PingFangTC-light;">这里我们可以看到镜像名称为docker-demo:1.1,docker容器为docker-server</span></p> <p><br></p> <h4 data-id="heading-20" style="text-align: left;">(9) 运行成功</h4> <p style="text-align: left;"><br></p> <figure style="text-align: left;"> <img data-height="709" data-ratio="0.7607296137339056" src="/upload/9725fd31a2952526a55ff4177275c0bf.png" data-type="other" data-w="932" data-width="932"> </figure> <p><br></p> <h4 data-id="heading-21" style="text-align: left;">(10) 浏览器访问</h4> <p style="text-align: left;"><br></p> <figure style="text-align: center;"> <img data-height="163" data-ratio="0.3140655105973025" src="/upload/e5f7a84d3e8aaceaf5dd1e43435ef62d.png" data-type="other" data-w="519" data-width="519"> </figure> <p style="text-align: left;">(11) 日志查看</p> <p><br></p> <figure style="text-align: center;"> <img data-height="62" data-ratio="0.22794117647058823" src="/upload/cc2bd9a98effd5deed1efc024d0e7709.png" data-type="other" data-w="272" data-width="272"> </figure> <p><br></p> <p style="text-align: left;"><span style="font-size: 16px;font-family: Optima-Regular, PingFangTC-light;">自此通过idea 部署springboot项目到docker成功!难以想象,部署一个Javaweb项目竟然如此简单方便!</span></p> <p style="white-space: normal;"><br></p> <section donone="shifuMouseDownCard('shifu_c_030')" label="Copyright Reserved by PLAYHUDONG." style="margin-top: 1em;margin-bottom: 1em;white-space: normal;text-align: start;color: rgb(0, 0, 0);border-width: 0px;border-style: initial;border-color: initial;"> <section style="margin-left: 1em;line-height: 1.4;"> <span style="padding: 3px 8px;border-radius: 4px;color: rgb(255, 255, 255);background-color: rgb(255, 105, 31);font-family: inherit;text-align: inherit;text-decoration: inherit;font-size: 16px;">推荐阅读</span> <span style="margin-left: 4px;padding: 3px 8px;border-radius: 1.2em;color: rgb(255, 255, 255);line-height: 1.2;background-color: rgb(204, 204, 204);font-family: inherit;text-align: inherit;text-decoration: inherit;border-color: rgb(249, 110, 87);font-size: 12px;">点击标题可跳转</span> </section> <section style="margin-top: -11px;padding: 22px 16px 16px;border-width: 1px;border-style: solid;border-color: rgb(255, 105, 31);color: rgb(51, 51, 51);font-size: 1em;font-family: inherit;text-align: inherit;text-decoration: inherit;"> <p><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MjM5NzMyMjAwMA==&mid=2651489975&idx=2&sn=9a645c6b1d3a21d3e84224547ab51990&chksm=bd25eac88a5263dee0c4caf5725b858301f0e07a8265a830994868a710da46d5dea9353a58ed&scene=21#wechat_redirect" data-itemshowtype="0" tab="innerlink" style="font-size: 12px;" data-linktype="2"><span style="font-size: 12px;">IDEA 上位?不!Eclipse Theia 1.0 发布!</span></a><br></p> <p style="letter-spacing: 0.544px;text-align: start;white-space: normal;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 16px;background-color: rgb(255, 255, 255);"><span style="font-size: 12px;letter-spacing: 0.544px;"><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MjM5NzMyMjAwMA==&mid=2651489843&idx=1&sn=c1bcf8763dd0dfffdbda90fe1b989dca&chksm=bd25ea4c8a52635a3f26f8aba89cc2d41f1d058578c4cffd7e92c7eec08b3e0fd22ee251fb1c&scene=21#wechat_redirect" data-itemshowtype="0" tab="innerlink" data-linktype="2" hasload="1" style="color: var(--weui-LINK);-webkit-tap-highlight-color: rgba(0, 0, 0, 0);cursor: pointer;">MySQL 常用分库分表方案,都在这里了!</a><br></span></p> <p style="letter-spacing: 0.544px;text-align: start;white-space: normal;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 16px;background-color: rgb(255, 255, 255);"><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MjM5NzMyMjAwMA==&mid=2651489971&idx=1&sn=90a13fc411172622503f1e7d980318eb&chksm=bd25eacc8a5263da038894fb47a3ed21393b8342f42111a7675cd8dc36d80f0baa89d515b3c9&scene=21#wechat_redirect" data-itemshowtype="0" tab="innerlink" data-linktype="2" hasload="1" style="color: var(--weui-LINK);-webkit-tap-highlight-color: rgba(0, 0, 0, 0);cursor: pointer;font-size: 12px;">踩坑了,JDK8中HashMap依然会产生死循环问题!</a><span style="font-size: 12px;letter-spacing: 0.544px;text-align: inherit;text-decoration: inherit;"></span></p> </section> </section> <p style="white-space: normal;color: rgb(0, 0, 0);text-align: start;"><br></p> <p style="white-space: normal;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);text-align: center;"><span style="font-size: 14px;color: rgb(255, 169, 0);">看完本文有收获?请转发分享给更多人</span></p> <p style="white-space: normal;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);text-align: center;"><strong style="color: rgb(255, 169, 0);">关注「ImportNew」,提升Java技能</strong></p> <p style="white-space: normal;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);text-align: center;"><img data-ratio="0.9166666666666666" data-s="300,640" data-type="jpeg" data-w="600" width="auto" src="/upload/899866149276fa5fddb73c61ae04be64.jpg" style="box-sizing: border-box !important;visibility: visible !important;width: 600px !important;"></p> <p style="white-space: normal;text-align: right;"><span style="font-size: 14px;">好文章,我</span><span style="font-size: 14px;color: rgb(255, 41, 65);">在看</span><span style="font-size: 14px;">❤️</span><span style="font-family: Optima-Regular, PingFangTC-light;font-size: 13px;letter-spacing: 1.5px;text-align: center;background-color: rgb(255, 255, 255);color: rgb(62, 62, 62);widows: 1;word-spacing: 2px;"></span></p>
作者:微信小助手
<section style="line-height: 1.75em;" data-mpa-powered-by="yiban.io"> <span style="font-size: 15px;letter-spacing: 1px;">职业生涯的前五年,基本上都在做<strong>即时通讯</strong>业务,由于业务的特殊性,吞吐量极大,时延不这么敏感,团队内部单独开发了一套纯异步omni框架。</span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;"> </span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;">学习omni框架内核,对职业生涯的提升极大,<strong>协议设计与实现</strong>,<strong>底层网络通信</strong>,<strong>多线程同步与互斥</strong>,<strong>同步RPC</strong>,<strong>异步RPC</strong>,<strong>服务器框架</strong>… 掌握了一套RPC内核原理与细节,基本上国内大部分公司的offer能手到擒来。</span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;"> </span> </section> <section style="line-height: 1.75em;"> <strong><span style="font-size: 15px;letter-spacing: 1px;">很多朋友问,如何学习RPC内核知识?</span></strong> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;">我的回答是,</span> <span style="font-size: 15px;letter-spacing: 1px;color: rgb(255, 76, 0);">直接看源码</span> <span style="font-size: 15px;letter-spacing: 1px;">。</span> </section> <section style="line-height: 1.75em;"> <br> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;">代码面前,没有秘密,<strong>看源码,写demo,单步调试</strong>,比听任何大神吹牛,比看任何理论书籍,都来得直接。</span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;"> </span> </section> <section style="line-height: 1.75em;"> <strong><span style="font-size: 15px;letter-spacing: 1px;">又有朋友问,目前开源的brpc以及thrift,都太重了,有没有更轻量级的服务端框架呢?</span></strong> <span style="font-size: 15px;letter-spacing: 1px;"></span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;">这里,我强烈推荐,</span> <span style="font-size: 15px;letter-spacing: 1px;color: rgb(255, 76, 0);">搜狗开源的轻量级高性能服务器引擎WF</span> <span style="font-size: 15px;letter-spacing: 1px;">:</span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;">(1)看其代码,及其清爽易懂;</span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;">(2)demo简单,单步调试容易;</span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;">(3)doc比较全,doc与src同步更新,比起行业内一些“为了开源而开源”的KPI项目,显得有诚意多了;</span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;"><br></span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;">个人觉得搜狗的WF框架,是目前国内开源的服务器引擎中<strong>最适合学习的</strong>。</span> </section> <section style="line-height: 1.75em;"> <span style="color: rgb(0, 128, 255);"><em><span style="font-size: 15px;letter-spacing: 1px;">画外音:文末有github地址。</span></em></span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;"> </span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;">这里,把自己的学习心得,以及大家可能关心的问题,简单聊一聊。</span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;"> </span> </section> <section style="line-height: 1.75em;"> <strong><span style="font-size: 15px;letter-spacing: 1px;">什么是WF,它是一个娱乐级框架,还是一个工业级框架?</span></strong> <span style="font-size: 15px;letter-spacing: 1px;"></span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;">WF,是搜狗开源的C++服务器引擎框架。</span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;"> </span> </section> <section style="line-height: 1.75em;"> <strong><span style="font-size: 15px;letter-spacing: 1px;">WF的设计目标是</span></strong> <span style="font-size: 15px;letter-spacing: 1px;">:</span> <span style="font-size: 15px;letter-spacing: 1px;color: rgb(255, 76, 0);">轻量级,高性能</span> <span style="font-size: 15px;letter-spacing: 1px;">。</span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;"> </span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;">轻量级,是指简洁,搜狗几乎所有的C++后端服务,包含但不限于搜索,输入法,广告等都是基于这个框架,每天处理超过百亿的请求,它是一个已经<strong>经过多年线上考验的工业级框架</strong>。</span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;"> </span> </section> <section style="line-height: 1.75em;"> <strong><span style="font-size: 15px;letter-spacing: 1px;">轻量级, WF真的做到了吗?</span></strong> <span style="font-size: 15px;letter-spacing: 1px;"></span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;">大伙可以看下,用WF如何搭建http服务器:</span> </section> <p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="0.4694708276797829" data-s="300,640" src="/upload/c285fe29c7671b8d7516d09bba9ac911.png" data-type="png" data-w="737" style=""></p> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;">这一段代码单步执行下来,IO线程,工作线程,任务队列,线程同步互斥机制,超时处理机制,异常处理机制… 对于一个服务器框架,基本就拿下七八成。</span> <br> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;"> </span> </section> <section style="line-height: 1.75em;"> <strong><span style="font-size: 15px;letter-spacing: 1px;">高性能,WF真的做到了吗?</span></strong> <span style="font-size: 15px;letter-spacing: 1px;"></span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;">大伙可以看下,WF的单机压测表现:</span> </section> <p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="0.6023809523809524" data-s="300,640" src="/upload/e8b3162f817e381c6a896d3b4cf0312a.png" data-type="png" data-w="840" style=""></p> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;">你没有看错,单机每秒50W的QPS,特别是高并发压测的情况下,比nginx和brpc表现都要好。</span> <br> </section> <section style="line-height: 1.75em;"> <span style="color: rgb(0, 128, 255);"><em><span style="font-size: 15px;letter-spacing: 1px;">画外音:</span></em></span> </section> <section style="line-height: 1.75em;"> <span style="color: rgb(0, 128, 255);"><em><span style="font-size: 15px;letter-spacing: 1px;">(1)测试硬件:CPU 40 core @ 2.20GHz,内存192G,网卡25000Mb/s;</span></em></span> </section> <section style="line-height: 1.75em;"> <span style="color: rgb(0, 128, 255);"><em><span style="font-size: 15px;letter-spacing: 1px;">(2)并发配置:nginx auto进程数为40,brpc配置nthreads为40,WF配置16个poller线程与20个handler线程;</span></em></span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;"> </span> </section> <section style="line-height: 1.75em;"> <strong><span style="font-size: 15px;letter-spacing: 1px;">除了轻量级与高性能,WF还有哪些特点?</span></strong> <span style="font-size: 15px;letter-spacing: 1px;"></span> </section> <section style="line-height: 1.75em;"> <br> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;">除了核心设计目标的两点,WF还有以下优势:</span> </section> <section style="line-height: 1.75em;"> <strong><span style="font-size: 15px;letter-spacing: 1px;">(1)易用性</span></strong> <span style="font-size: 15px;letter-spacing: 1px;"></span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;">相比go语言的简单,天下苦C++久矣,虽然C++后续也推出了各种简易用法,但并不是所有用户了解与掌握,目前WF的标准是C++11,把很多复杂性都进行了屏蔽。</span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;"> </span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;">用户再也不用关注连接池、线程池、文件句柄,以及各种异步通知机制,WF都进行了封装与细节屏蔽。</span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;"> </span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;">使用WF,<strong>用户只需要关注两个核心概念</strong>:<strong>任务</strong></span> <span style="letter-spacing: 1px;font-size: 12px;">(task)</span> <span style="font-size: 15px;letter-spacing: 1px;">与<strong>任务流</strong></span> <span style="letter-spacing: 1px;font-size: 12px;">(series)</span> <span style="font-size: 15px;letter-spacing: 1px;">。</span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;"> </span> </section> <section style="line-height: 1.75em;"> <strong><span style="font-size: 15px;letter-spacing: 1px;">(2)通信与计算一体的解决方案</span></strong> <span style="font-size: 15px;letter-spacing: 1px;"></span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;">大部分RPC框架着重解决通信的问题,而计算与任务调度框架需要用户自己实现,而WF框架则将二者融为一体,一并解决了。</span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;"> </span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;">WF把网络,CPU,磁盘IO,GPU,计时器,计数器都进行了封装,统一当成资源,使用者可以任意进行调度与组合,而不需要关注其底层的epoll,pthread,aio,cuda,timer_fd,count计数等。</span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;"> </span> </section> <section style="line-height: 1.75em;"> <strong><span style="font-size: 15px;letter-spacing: 1px;">(3)架构层次良好,非常方便业务逻辑的实现</span></strong> <span style="font-size: 15px;letter-spacing: 1px;"></span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;">WF对于业务逻辑处理进行了抽象:</span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;">第一,串行由任务组成;</span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;">第二,并行由串行组成;</span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;">第三,并行是一种任务;</span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;"> </span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;">任务和任务流是WF的基石,WF本身就是一套完备的、可以收敛的、容易控制的业务逻辑任务流模型。</span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;"> </span> </section> <section style="line-height: 1.75em;"> <strong><span style="font-size: 15px;letter-spacing: 1px;">(4)文档很全</span></strong> <span style="font-size: 15px;letter-spacing: 1px;"></span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;">除了轻量级,简单易用之外,其文档和demo非常齐全,对于新手及其友好。而且碰到代码中不明白的地方,可以直接联系开发小组,作者会直接和大家交流,避免二手消息。</span> </section> <p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="0.52578125" data-s="300,640" src="/upload/145c7aff32e5b825e3bad6faaec9c10a.png" data-type="png" data-w="1280" style=""></p> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;">这也是推荐WF成为大家学习上手的框架,很重要的原因。</span> <br> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;"> </span> </section> <section style="line-height: 1.75em;"> <strong><span style="font-size: 15px;letter-spacing: 1px;">可能有朋友会问,说框架太宏观,研究WF,具体能学到哪些技术内容呢?</span></strong> <span style="font-size: 15px;letter-spacing: 1px;"></span> </section> <section style="line-height: 1.75em;"> <br> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;">简单的举几个例子:</span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;">(1)<strong>学习错误处理</strong>:为了提升性能,WF没有使用异常,研究WF能系统性学习错误处理,帮助我们写出极高质量的代码;</span> </section> <section style="line-height: 1.75em;"> <span style="color: rgb(0, 128, 255);"><em><span style="color: rgb(0, 128, 255);font-size: 15px;letter-spacing: 1px;">画外音:扪心自问,去掉异常,你写的代码会不会随时崩溃。</span></em></span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;"> </span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;">(2)<strong>学习超时处理</strong>:各种通信超时,任务超时,你真的理解其内核么?超时的原因与处理,WF是学习利器。</span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;"> </span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;">(3)<strong>学习异步IO</strong>:Linux支持非常高效的异步IO系统调度,如何使用这些异步IO去实现框架,去封装任务,实现业务逻辑任务流化,看看WF的玩法。</span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;"> </span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;">(4)<strong>学习协议设计</strong>:学习如何利用WF框架,实现brpc和thrift,实现自己自定义的client/server协议,实现自己的RPC系统。</span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;"> </span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;">(5)<strong>学习计时器与计数器</strong>:很有朋友timer和count用的非常多,但它底层是怎么实现的,值得深入研究。</span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;"> </span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;">(6)<strong>学习服务治理</strong>:WF有一套完整的服务治理方案,包含<strong>服务路由,熔断与恢复,负载均衡,服务主备。可用于实现服务发现与服务网格</strong></span> <span style="letter-spacing: 1px;font-size: 12px;">(service mesh)</span> <span style="font-size: 15px;letter-spacing: 1px;">系统。</span> </section> <section style="line-height: 1.75em;"> <span style="color: rgb(0, 128, 255);"><em><span style="color: rgb(0, 128, 255);font-size: 15px;letter-spacing: 1px;">画外音:这一部分,可以查看源码的upstream子模块。</span></em></span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;"> </span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;">(7)…</span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;">今年,看的最清爽的代码,最适合了解通信内核,RPC内核,调度框架内核的引擎,强烈推荐给大家。</span> <span style="font-size: 15px;letter-spacing: 1px;">欢迎大家Fork,欢迎大家标星。</span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;"><br></span> </section> <section style="line-height: 1.75em;"> <strong><span style="font-size: 15px;letter-spacing: 1px;">地址</span></strong> <span style="font-size: 15px;letter-spacing: 1px;">:https://github.com/sogou/workflow</span> </section> <section style="line-height: 1.75em;"> <strong><span style="font-size: 15px;letter-spacing: 1px;">Star</span></strong> <span style="font-size: 15px;letter-spacing: 1px;">:1400+</span> </section> <section style="line-height: 1.75em;"> <span style="color: rgb(0, 128, 255);"><em><span style="color: rgb(0, 128, 255);font-size: 15px;letter-spacing: 1px;">画外音:WF还有很多优秀的设计,等待大家去挖掘。</span></em></span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;"></span> </section> <section style="line-height: 1.75em;"> <br> </section> <section style="line-height: 1.75em;"> <strong><span style="font-size: 15px;letter-spacing: 1px;">阅读原文</span></strong> <span style="font-size: 15px;letter-spacing: 1px;">,</span> <span style="font-size: 15px;letter-spacing: 1px;color: rgb(255, 76, 0);">直达代码</span> <span style="font-size: 15px;letter-spacing: 1px;">,<span style="font-size: 15px;letter-spacing: 1px;">好的代码,一起分享。</span></span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;"></span> </section>
作者:微信小助手
<section style="box-sizing: border-box;font-style: normal;font-weight: 400;text-align: justify;font-size: 16px;"> <section style="margin-top: 10px;margin-bottom: 10px;box-sizing: border-box;"> <section style="padding: 10px 10px 0px;background-color: rgb(239, 239, 239);box-sizing: border-box;"> <span style="display: inline-block;width: 5%;line-height: 0.8;font-weight: bolder;font-size: 48px;box-sizing: border-box;" title=""> <section style="box-sizing: border-box;"> “ </section></span> <section style="display: inline-block;vertical-align: top;float: right;width: 90%;line-height: 1.5;font-size: 15px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="margin: 0px;padding: 0px;box-sizing: border-box;"><span style="letter-spacing: 1px;">好的代码往往也很好看!代码是给机器运行的,但同样也是给人看的,并且随着上线还需要由人来运维。那么写出可扩展、易维护、好读懂的代码就显得非常重要。</span></p> </section> <section style="clear: both;box-sizing: border-box;"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> </section> </section> </section> <section style="line-height: 1.75em;"> <br> </section> <section style="text-align: center;margin-left: 8px;margin-right: 8px;"> <img class="rich_pages" data-ratio="0.664321608040201" data-s="300,640" src="/upload/9281dc23ada8977e3a01e0f06ab6e912.png" data-type="png" data-w="995" style=""> </section> <section style="text-align: center;line-height: 1.75em;"> <span style="font-size: 14px;color: rgb(89, 89, 89);letter-spacing: 1px;"><em>图片来自 Pexels</em></span> <br> </section> <section style="line-height: normal;"> <br> </section> <section data-tool="mdnice编辑器" data-website="https://www.mdnice.com"> <section data-tool="mdnice编辑器" data-website="https://www.mdnice.com"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;"></span> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">对于新人来说,互联网大厂项目开发与平常自己学习的代码还是有很大的差别的。日常学习时候通常只要能运行出结果即可,并不会有其他的要求。<br></span></p> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">也不会说有;PRD 评审、研发设计评审、代码开发、代码评审以及中间一些列的提交物,直到测试完成,上线验证,开量对外等等。<br></span></p> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">所以很多新人刚从学校毕业或者从小公司进入大厂,在规范制约下会有一些不习惯,甚至犯错误。<br></span></p> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">那么为了让大家更好的知晓这些问题,我特意整理了一些例子,欢迎参考。<br></span></p> <section style="line-height: normal;"> <br> </section> <section style="box-sizing: border-box;font-style: normal;font-weight: 400;text-align: justify;font-size: 16px;"> <section style="border-bottom: 1px solid black;margin: 0.5em 0px;line-height: 1.2;box-sizing: border-box;"> <section style="display: inline-block;border-color: rgb(89, 89, 89);border-bottom: 6px solid rgb(89, 89, 89);margin-bottom: -1px;font-size: 20px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="margin: 0px;padding: 0px;box-sizing: border-box;">会议室</p> </section> </section> </section> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">谢飞机,刚刚入职没多久,兴奋的写着 Leader 给的需求,码的飞快。恰巧组长走过来:“飞机,带着你的电脑,跟我来会议室,做下代码评审。”<br></span></p> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">Leader:</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">飞机,你这代码咋这么粗鲁!<br></span></p> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">飞机:</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">啊?😱<br></span></p> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">Leader:</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">我要不拦着你,我感觉你这代码都能飞。<br></span></p> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">Leader:</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">你看哈,就说这行,这日志打的,上线后出了问题,你能查到原因吗?<br></span></p> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">飞机:</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">好像...<br></span></p> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">Leader:</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">还有这,这 idea 都提示你了,都报黄色了,你怎么不看看。还有,这代码也不格式化,一个月后它认识你,你还认识它吗。<br></span></p> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">Leader:</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">给你发的入职编码规范看了?<br></span></p> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">飞机:</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">哦,看一些,写的时候忘了。<br></span></p> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">Leader:</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">先别着急写,看会了再写代码,这还有一个不错的工程,可以参考。<br></span></p> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">写代码不是以完成功能就算完事,还需要写的漂亮。评审后,飞机,坐回工位,收起了躁动的心,安心熟读手册并练习。<br></span></p> <p style="line-height: normal;"><br></p> <section style="box-sizing: border-box;font-style: normal;font-weight: 400;text-align: justify;font-size: 16px;"> <section style="border-bottom: 1px solid black;margin: 0.5em 0px;line-height: 1.2;box-sizing: border-box;"> <section style="display: inline-block;border-color: rgb(89, 89, 89);border-bottom: 6px solid rgb(89, 89, 89);margin-bottom: -1px;font-size: 20px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="margin: 0px;padding: 0px;box-sizing: border-box;">代码评审</p> </section> </section> </section> <section style="line-height: normal;"> <br> </section> <h3 data-tool="mdnice编辑器" style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">①日志规范</span></strong></h3> <p style="line-height: normal;"><br></p> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">日志是整个代码开发过程中非常重要的环节,如果日志打的不好,那么遇到的线上 Bug 就没法快速定位,定位不了问题也就没法快速解决问题。直接带来的结果可能包括;客诉更多、资损更大、修复更慢。<br></span> </section> <section style="font-size: 16px;color: rgb(62, 62, 62);line-height: 1.6;word-spacing: 0px;letter-spacing: 0px;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;"> <pre style="font-size: inherit;color: inherit;line-height: inherit;margin: 0px;padding: 0px;"><code style="white-space:pre-wrap;overflow-wrap: break-word;margin: 0px 2px;line-height: 18px;font-size: 14px;font-weight: normal;word-spacing: 0px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;color: rgb(169, 183, 198);background: rgb(40, 43, 46);overflow-x: auto;padding: 0.5em;word-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;margin: 0px;padding: 0px;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">public</span> Result execRule(RuleReq req) {<br> <span style="font-size: inherit;line-height: inherit;margin: 0px;padding: 0px;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">try</span> {<br> logger.info(<span style="font-size: inherit;line-height: inherit;margin: 0px;padding: 0px;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">"执行服务规则 req:{}"</span>, JSON.toJSONString(req));<br> <span style="font-size: inherit;line-height: inherit;margin: 0px;padding: 0px;color: rgb(128, 128, 128);word-wrap: inherit !important;word-break: inherit !important;">// 业务流程</span><br> <span style="font-size: inherit;line-height: inherit;margin: 0px;padding: 0px;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">return</span> Result.buildSuccess();<br> } <span style="font-size: inherit;line-height: inherit;margin: 0px;padding: 0px;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">catch</span> (Exception e) {<br> logger.error(<span style="font-size: inherit;line-height: inherit;margin: 0px;padding: 0px;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">"执行服务规则失败"</span>, e);<br> <span style="font-size: inherit;line-height: inherit;margin: 0px;padding: 0px;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">return</span> Result.buildError(e);<br> }<br>}<br></code></pre> </section> <section style="line-height: normal;"> <br> </section> <p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">就像上面这段代码中的日志:</span></p> <ul style="list-style-type: disc;" class="list-paddingleft-2"> <li><p style="text-align: justify;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">看似没什么问题,但在这段异常代码中,没有打方法的入参信息。如果方法异常时只是抛出一些异常栈信息,那么是很难定位具体的由次调用触发的。</span></p></li> <li> <section style="text-align: justify;line-height: 1.75em;margin-bottom: 5px;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">另外如果你的系统监控服务,没有类似方法跟踪 ID 的功能,最好还需要在日志中把本次调用具有标识性的 id,作为查询条件打到日志中。</span> <br> </section></li> </ul> <section style="font-size: 16px;color: rgb(62, 62, 62);line-height: 1.6;word-spacing: 0px;letter-spacing: 0px;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;"> <pre style="font-size: inherit;color: inherit;line-height: inherit;margin: 0px;padding: 0px;"><code style="white-space:pre-wrap;overflow-wrap: break-word;margin: 0px 2px;line-height: 18px;font-size: 14px;font-weight: normal;word-spacing: 0px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;color: rgb(169, 183, 198);background: rgb(40, 43, 46);overflow-x: auto;padding: 0.5em;word-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;margin: 0px;padding: 0px;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">public</span> Result execRule(RuleReq req) {<br> <span style="font-size: inherit;line-height: inherit;margin: 0px;padding: 0px;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">try</span> {<br> logger.info(<span style="font-size: inherit;line-height: inherit;margin: 0px;padding: 0px;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">"执行服务规则{}开始 req:{}"</span>, req.getrId(), JSON.toJSONString(req));<br> <span style="font-size: inherit;line-height: inherit;margin: 0px;padding: 0px;color: rgb(128, 128, 128);word-wrap: inherit !important;word-break: inherit !important;">// 业务流程</span><br> logger.info(<span style="font-size: inherit;line-height: inherit;margin: 0px;padding: 0px;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">"执行服务规则{}完成 res:{}"</span>, req.getrId(), <span style="font-size: inherit;line-height: inherit;margin: 0px;padding: 0px;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">"业务流程,必要的结果信息"</span>);<br> <span style="font-size: inherit;line-height: inherit;margin: 0px;padding: 0px;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">return</span> Result.buildSuccess();<br> } <span style="font-size: inherit;line-height: inherit;margin: 0px;padding: 0px;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">catch</span> (Exception e) {<br> logger.error(<span style="font-size: inherit;line-height: inherit;margin: 0px;padding: 0px;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">"执行服务规则{}失败 req:{}"</span>, req.getrId(), JSON.toJSONString(req), e);<br> <span style="font-size: inherit;line-height: inherit;margin: 0px;padding: 0px;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">return</span> Result.buildError(e);<br> }<br>}<br></code></pre> </section> <section style="line-height: normal;"> <br> </section> <p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">修改后的日志如上:</span></p> <ul style="list-style-type: disc;" class="list-paddingleft-2"> <li><p style="text-align: justify;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">那么现在这样改成这样打日志,就可以非常方便的查询问题,例如搜索;执行服务规则 100098921,那么它的一整串关于这次调用的信息就可以都搜索出来了,方便排查问题。</span></p></li> <li><p style="text-align: justify;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">在异常中打印入参是为了更加方便的定位问题,不需要比对上下文。</span></p></li> <li><p style="text-align: justify;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">打日志还有很多技巧,但所有打的日志目的都为了在出问题时可以快速定位问题,但也注意不要打太多日志,精简好用即可。</span></p></li> </ul> <h3 data-tool="mdnice编辑器" style="line-height: normal;"><br></h3> <h3 data-tool="mdnice编辑器" style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">②IDEA 提示</span></strong></h3> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">很多时候因为你,走神、疏忽、手滑,写出来的错误代码,IntelliJ IDEA,都会给你警告⚠提示,只是你,没有去看、没有去看、没有去看!<br></span></p> <section style="line-height: normal;"> <br> </section> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"> <span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">来自 idea 的警告:</span> </section> <p style="text-align: center;margin-left: 8px;margin-right: 8px;margin-bottom: 5px;"><img class="rich_pages" data-ratio="0.6662162162162162" data-s="300,640" src="/upload/4d1368e83c3575b9fe748cd8b51f3452.jpg" data-type="jpeg" data-w="740" style=""></p> <p style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 14px;color: rgb(89, 89, 89);letter-spacing: 1px;"><em>idea 警告</em></span></p> <section style="line-height: normal;"> <br> </section> <section style="text-align: justify;line-height: 1.75em;margin-left: 8px;margin-right: 8px;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">idea 在警告提示这方面非常优秀,只要你能看得见,按照它的提示修改,就可以减少很多的错误。如果你还希望有更强的提示,那么你可以按照 p3c 插件,帮你检查代码错误。</span> </section> <h3 data-tool="mdnice编辑器" style="line-height: normal;"><br></h3> <h3 data-tool="mdnice编辑器" style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">③代码格式</span></strong></h3> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">可能这并不是一个致命的问题,但代码格式化最大的好处是,提升可读性、规整性、以及可以让整组人都在一个标准下执行。<br></span></p> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">因为很多时候一个组的程序员,会在一个类下开发,有人格式化、有人不格式化除了不好看以外,合并代码有时候也会遇到麻烦。<br></span></p> <section style="line-height: normal;"> <br> </section> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"> <span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">不格式化的代码缺少灵魂:</span> </section> <section style="text-align: center;margin-bottom: 5px;"> <img class="rich_pages" data-ratio="0.5590909090909091" data-s="300,640" src="/upload/639e24dbb21b262834525605427a2bc2.jpg" data-type="jpeg" data-w="440" style=""> </section> <figure data-tool="mdnice编辑器"> <p style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="color: rgb(89, 89, 89);font-size: 14px;letter-spacing: 1px;"><em>代码格式化</em></span></p> <section style="line-height: normal;"> <br> </section> </figure> <section style="text-align: justify;line-height: 1.75em;margin-left: 8px;margin-right: 8px;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">对于严格要自己的程序员来说,代码没有格式化还是很难受的。看一段代码,只要发现差一个空格位置,都知道这是格式化还是没格式化。</span> </section> <h3 data-tool="mdnice编辑器" style="line-height: normal;"><br></h3> <h3 data-tool="mdnice编辑器" style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">④单元测试</span></strong></h3> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">单测?覆盖率?写代码不是写完就可以了吗?<br></span></p> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">当然不是,你写的代码你需要保证它能你跑通你所有的流程节点,确保这份功能是没有问题的,才能提交给测试,否则来回反复,耗时耗力。<br></span></p> <section style="line-height: normal;"> <br> </section> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">这也就是写单测的目的!甚至好一点的研发可以通过单测驱动开发,在这个阶段能把一些共用的方法合并、抽离,避免过多的冗余方法。<br></span> </section> <p style="text-align: center;margin-left: 8px;margin-right: 8px;margin-bottom: 5px;"><img class="rich_pages" data-ratio="0.3787037037037037" data-s="300,640" src="/upload/fc33479f96a0e11ecc38030db8cd97b1.jpg" data-type="jpeg" data-w="1080" style=""></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">单测长什么样,如上图:</span><br></p> <ul style="list-style-type: disc;" class="list-paddingleft-2"> <li><p style="text-align: justify;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">单测完整基本也就是代码的健壮性更好,能把单测写好,基本提交的代码就不会有那么多测试妹子找你聊天。</span></p></li> <li><p style="text-align: justify;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">在很多公司中一般都会要求单测覆盖率超过多少,否则是不允许编译提交的,这有插件可以和 Jenkins 配合使用。</span></p></li> </ul> <h3 data-tool="mdnice编辑器" style="line-height: normal;"><br></h3> <h3 data-tool="mdnice编辑器" style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">⑤分支规范</span></strong></h3> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">可能有些人看到分支规范根本没有感觉,因为他们开发的项目较小,没有多人开发,上线周期也短,也不会开发中添加需求。<br></span></p> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">但在互联网中并不是这样,往往一个系统需要几个人维护,并同时进行开发。一般这里会包括 master 分支、test 分支、本次需求的分支。<br></span></p> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">有这么多分支怎么用呢,如下:</span></p> <ul style="list-style-type: disc;" class="list-paddingleft-2"> <li><p style="text-align: justify;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">master 分支,</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">是主分支,也是上线分支,不允许在上面直接修改代码。</span></p></li> <li><p style="text-align: justify;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">test 分支,</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">是测试环境分支,每个人都需要把自己开发完的分支,提测后合并到 test 分支,交由测试验证。</span></p></li> <li><p style="text-align: justify;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">需求分支</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">,也是个人开发的分支,同一个需求下,大家在这个分支写代码,当然也可能这个系统模块的分支就一个人在开发。</span></p></li> </ul> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">重点,如果有人不遵守分支规范或者压根没概念,把自己的需求代码写在 test 分支上,并且是多次修改提交都在 test 分支写。那么就危险了,严重会耽误上线。<br></span></p> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">为什么?</span></p> <ul style="list-style-type: disc;" class="list-paddingleft-2"> <li><p style="text-align: justify;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">test 分支,是由大家把自己的代码合并过来共用的,那么这个分支就会包含 2 个或者更多的并行需求,当你需要上线的时候,需要把自己的代码合并到 master,但 test 分支代码是不能合并到 master 的,那么多未知的内容,根本没有在上线范围。</span></p></li> <li><p style="text-align: justify;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">那么你又想上线,又不能避开 test 分支,就需要把你写的代码,重新粘贴过去,这个时间成本非常大。</span></p></li> <li><p style="text-align: justify;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">test 分支,还随时有删除重新拉的可能,如果有人通知大家删除重新拉,那你的代码就会丢失。</span></p></li> </ul> <h3 data-tool="mdnice编辑器" style="line-height: normal;"><br></h3> <h3 data-tool="mdnice编辑器" style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">⑥夹带需求</span></strong></h3> <section style="line-height: normal;"> <br> </section> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;"></span> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">提交测试,但还藏一个需求。<br></span></strong></p> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;"></span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">研发开发需求代码时候,有时候会额外加一些其他代码,而且这些代码可能跟本次需求并没有关系。<br></span></p> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">那为什么会这样呢?</span></p> <ul style="list-style-type: disc;" class="list-paddingleft-2"> <li><p style="text-align: justify;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">以前留下来的 Bug,想修复下,但忘记告知测试。</span></p></li> <li><p style="text-align: justify;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">在开发这个需求时,其他产品又找过来让加功能,并说功能很小,没有发邮件通知相关测试人员。</span></p></li> <li><p style="text-align: justify;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">看到某块以前写的代码太乱了,就想着优化下,自信心很高,不必告诉测试。</span></p></li> </ul> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">那这时候你提交的代码,如果不在测试范围又出了问题,只能研发自己抗。并且在所有的研发团队,几乎是不会让夹带需求上线的,这样的做完了不算功劳,做出了问题还会被骂。<br></span></p> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">所以,千万不要私自夹带!哪怕你是好心!<br></span></p> <p style="line-height: normal;"><br></p> <h3 data-tool="mdnice编辑器" style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">⑦异常流程</span></strong></h3> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">擦屁屁的纸,80% 的面积都是保护手的!</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;"><br></span></p> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">这句话是我经常用的,因为我们编程很多时候都是在处理异常流程,正常流程往往并不难,难的是分析出这段开发的代码有多少异常流程有没有处理。<br></span></p> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">那么,会有哪些异常呢?</span></p> <ul style="list-style-type: disc;" class="list-paddingleft-2"> <li><p style="text-align: justify;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">支付成功 MQ 消息发送失败,需要 worker 补偿。</span></p></li> <li><p style="text-align: justify;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">PRC 接口调用失败,网络超时,实际成功。</span></p></li> <li><p style="text-align: justify;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">接口幂等性,多次调用结果一致性。</span></p></li> </ul> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">等等,这些都是异常流程,尤其在一些交易提现环节,会出现各种异常,那么不可能把这些异常都反馈用户展示到界面。<br></span></p> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">而是要有一些非常友好的提示,并且在服务端的流程里,有一定的补偿机制,来保证最终的调用成功,或者逆反。<br></span></p> <p style="line-height: normal;"><br></p> <h3 data-tool="mdnice编辑器" style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">⑧代码成坨</span></strong></h3> <p style="line-height: normal;"><br></p> <section style="text-align: center;margin-left: 8px;margin-right: 8px;"> <img class="rich_pages" data-ratio="1.0631443298969072" data-s="300,640" src="/upload/6f821d0b5d0efe8427e71bfcadfee93.jpg" data-type="jpeg" data-w="776" style=""> </section> <section style="text-align: center;line-height: 1.75em;"> <span style="font-size: 14px;color: rgb(89, 89, 89);letter-spacing: 1px;"><em>代码成坨</em></span> <br> </section> <section style="line-height: normal;"> <br> </section> <figure data-tool="mdnice编辑器"></figure> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">CRUD 往往可能是因为你的设计,换个人写也许不同。<br></span></strong></p> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;"></span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">很多时候研发写代码,根本不考虑是否要扩展,总之一个类+几十行 if else,能搞定所有需求。等下次在开发类似的,就粘贴过去再修修补补,能用就行。<br></span></p> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">缺少写出良好代码的研发,一方面是经历有限,另外一方面是学了很多理论但是不好落地。比如设计模式,但自己实际写代码的时候还是很晕。<br></span></p> <p style="line-height: normal;"><br></p> <h3 data-tool="mdnice编辑器" style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">⑨SQL 性能</span></strong></h3> <section style="line-height: normal;"> <br> </section> <section style="font-size: 16px;color: rgb(62, 62, 62);line-height: 1.6;word-spacing: 0px;letter-spacing: 0px;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;"> <pre style="font-size: inherit;color: inherit;line-height: inherit;margin: 0px;padding: 0px;"><code style="white-space:pre-wrap;overflow-wrap: break-word;margin: 0px 2px;line-height: 18px;font-size: 14px;font-weight: normal;word-spacing: 0px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;color: rgb(169, 183, 198);background: rgb(40, 43, 46);overflow-x: auto;padding: 0.5em;word-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;margin: 0px;padding: 0px;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">select</span> * <span style="font-size: inherit;line-height: inherit;margin: 0px;padding: 0px;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">from</span> <span style="font-size: inherit;line-height: inherit;margin: 0px;padding: 0px;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">table</span> <span style="font-size: inherit;line-height: inherit;margin: 0px;padding: 0px;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">where</span> <span style="font-size: inherit;line-height: inherit;margin: 0px;padding: 0px;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">status</span> = <span style="font-size: inherit;line-height: inherit;margin: 0px;padding: 0px;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">1</span> <span style="font-size: inherit;line-height: inherit;margin: 0px;padding: 0px;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">limit</span> <span style="font-size: inherit;line-height: inherit;margin: 0px;padding: 0px;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">200</span>;<br></code></pre> </section> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">这是一段定时任务扫描库表的 SQL,这段 SQL 会定时扫库,将库表中状态是 1 的扫描出来进行处理,每次扫描 200 行。<br></span></p> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">你发现有什么问题了吗?</span></p> <ul style="list-style-type: disc;" class="list-paddingleft-2"> <li><p style="text-align: justify;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">扫描必要字段即可,不需要全部字段。</span></p></li> <li><p style="text-align: justify;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">这段 SQL 会越来越慢,即使状态字段加了索引。因为 status 并不能大量排掉其他状态字段,随着数据越来越多依然是全表扫描。</span></p></li> </ul> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">那么怎么优化呢,其实优化也比较简单,需要先根据状态查询到符合条件的最小的 id,之后再 SQL 的查询条件中添加 id>xx,即可。<br></span></p> <section style="line-height: normal;"> <br> </section> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">另外如果你的任务需要多个 worker 扫描,增加效率,可以增加门牌号设计,提升扫描效率,如下:<br></span> </section> <section style="text-align: center;margin-left: 8px;margin-right: 8px;"> <img class="rich_pages" data-ratio="0.6851063829787234" data-s="300,640" src="/upload/ebf0e70c03713ca9f5888de061ba2f51.jpg" data-type="jpeg" data-w="940" style=""> </section> <p style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 14px;letter-spacing: 1px;"><em><span style="font-size: 14px;color: rgb(89, 89, 89);letter-spacing: 1px;">门牌号扫描</span></em></span></p> <figure data-tool="mdnice编辑器"></figure> <h3 data-tool="mdnice编辑器" style="line-height: normal;"><br></h3> <h3 data-tool="mdnice编辑器" style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">⑩结伴编程</span></strong></h3> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">评审代码最后这点想说说,陪伴式开发,可能这不是结伴编程,不是共同合作,而是一个研发需要另外一个研发不断的提供帮助。有时候可能就是很简单的问题,也不想查,或者说没有意识去查,只是问。<br></span></p> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">业务开发的过程,只要把流程定下来,研发设计评审完,其他的开发过程中遇到的小点并不难,只要查一查就可以搞定。<br></span></p> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">当日也不是说完全不能问,只不过特别普遍,简单的代码问题,自己搞定就可以了,但这个时候还像保姆似的陪伴,就会拖累整个团队的进展,最终大家都需要扛起那个慢的。<br></span></p> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">所以,如果你是那个需要陪伴的,要及早断奶,学会自己攻克,快速成长。而如果你是那个卷纸,可哪擦屁股的,要把卷纸传递给他。一个人擦一次是能力体现,反反复复擦一个人,就惹屎上身了。</span><br></p> <section style="line-height: normal;"> <br> </section> <section style="box-sizing: border-box;font-style: normal;font-weight: 400;text-align: justify;font-size: 16px;"> <section style="border-bottom: 1px solid black;margin: 0.5em 0px;line-height: 1.2;box-sizing: border-box;"> <section style="display: inline-block;border-color: rgb(89, 89, 89);border-bottom: 6px solid rgb(89, 89, 89);margin-bottom: -1px;font-size: 20px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="margin: 0px;padding: 0px;box-sizing: border-box;">总结</p> </section> </section> </section> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;color: rgb(71, 193, 168);">总结如下:</span><br></p> <ul style="list-style-type: disc;" class="list-paddingleft-2"> <li><p style="text-align: justify;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">以上介绍了代码评审中涉及到的比较常见的点,基本也是很多研发容易忽略和犯错误的地方。这些问题点拿出哪一个看,都不大,但运行在代码中,确都有可能发生致命或者麻烦的事情。</span></p></li> <li><p style="text-align: justify;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">想让自己能把代码写好,就不只面试时候造飞机的回答,什么时间复杂度、什么可重入锁、什么红黑树,什么 DDD,只要你不能正确的落地和运用这些技术,说的再多都是空谈。</span></p></li> <li><p style="text-align: justify;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">多学一些、多看一些、多问一些,没有坏处,但要自己能成长,把吸取到的经验心得,运用到业务开发中,写出可扩展、可维护的代码,才能让自己真的升职加薪。也能让既有留下的本事,也有出去的能力。</span></p></li> </ul> <section style="line-height: normal;"> <br> </section> <p style="white-space: normal;max-width: 100%;min-height: 1em;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;color: rgb(89, 89, 89);letter-spacing: 1px;box-sizing: border-box !important;word-wrap: break-word !important;"><em style="max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;"><span style="max-width: 100%;font-size: 14px;box-sizing: border-box !important;word-wrap: break-word !important;">作者:</span></em><em style="max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;"><span style="max-width: 100%;font-size: 14px;box-sizing: border-box !important;word-wrap: break-word !important;">小傅哥</span></em></span></p> <p style="white-space: normal;max-width: 100%;min-height: 1em;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;color: rgb(89, 89, 89);letter-spacing: 1px;box-sizing: border-box !important;word-wrap: break-word !important;"><em style="max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;"><span style="max-width: 100%;font-size: 14px;box-sizing: border-box !important;word-wrap: break-word !important;">简介:多年从事一线互联网 Java 开发,从 19 年开始编写工作和学习历程的技术汇总,旨在为大家提供一个较清晰详细的核心技能学习文档。</span></em></span></p> <p style="white-space: normal;max-width: 100%;min-height: 1em;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;color: rgb(89, 89, 89);letter-spacing: 1px;box-sizing: border-box !important;word-wrap: break-word !important;"><em style="max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;"><span style="max-width: 100%;font-size: 14px;box-sizing: border-box !important;word-wrap: break-word !important;">编辑:陶家龙</span></em></span><br style="max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;"></p> <p><em style="max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;"><span style="max-width: 100%;line-height: 1.75em;font-size: 14px;color: rgb(89, 89, 89);letter-spacing: 1px;box-sizing: border-box !important;word-wrap: break-word !important;">出处:转载自公众号 bugstack 虫洞栈(ID:bugstack)<br></span></em></p> <p style="text-align: center;"><img class="rich_pages" data-ratio="0.39375" src="/upload/eccf90ae5f48405df149baa3056d4bf3.png" data-type="gif" data-w="640" style=""></p> </section> <section style="box-sizing: border-box;font-style: normal;font-weight: 400;text-align: justify;font-size: 16px;"> <section style="margin: 0.5em 0px;box-sizing: border-box;"> <section style="font-size: 15px;border-style: solid;border-width: 0px 0px 1px;color: rgb(89, 89, 89);border-bottom: 1px solid rgba(215, 215, 215, 0.96);box-sizing: border-box;"> <p style="margin: 0px;padding: 0px;box-sizing: border-box;"><span style="letter-spacing: 1px;"><strong>精彩文章推荐:</strong></span></p> </section> </section> </section> <p style="line-height: 2em;"><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MjM5ODI5Njc2MA==&mid=2655836054&idx=2&sn=1ae5aa70acba615f1074be7946dfc2c9&chksm=bd749a418a031357efd4e637eb007079a867d7baad290db9727fa437628d64e8453d9b0fd308&scene=21#wechat_redirect" data-itemshowtype="0" tab="innerlink" style="font-size: 14px;color: rgb(89, 89, 89);letter-spacing: 1px;" data-linktype="2"><span style="font-size: 14px;color: rgb(89, 89, 89);letter-spacing: 1px;">删库造成损失0.87亿,微盟程序员被判6年!</span></a><br><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MjM5ODI5Njc2MA==&mid=2655836035&idx=1&sn=fb420553c05ff8d7ad08439034850499&chksm=bd749a548a0313428735f2bcbee249771772945e185602bfae208157c164bb1ed07286d4a5e0&scene=21#wechat_redirect" data-itemshowtype="0" tab="innerlink" style="font-size: 14px;color: rgb(89, 89, 89);letter-spacing: 1px;" data-linktype="2"><span style="font-size: 14px;color: rgb(89, 89, 89);letter-spacing: 1px;">Kafka都没整明白,还敢去面试?</span></a><br><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MjM5ODI5Njc2MA==&mid=2655835984&idx=3&sn=a068efcd3e14e38eec3e54ea1db3df60&chksm=bd749a878a031391f2d9e98cf064acae5e68e0619e11994cc0fb601f9d2bb121aefa2f6f2f70&scene=21#wechat_redirect" data-itemshowtype="0" tab="innerlink" style="font-size: 14px;color: rgb(89, 89, 89);letter-spacing: 1px;" data-linktype="2"><span style="font-size: 14px;color: rgb(89, 89, 89);letter-spacing: 1px;">漫画丨Linux内核到底长啥样?</span></a><br></p> </section>
作者:微信小助手
<section data-mpa-powered-by="yiban.io"> <span style="color: rgb(255, 76, 0);font-size: 16px;letter-spacing: 1px;background-color: rgb(255, 255, 255);font-family: Roboto, sans-serif;font-weight: 600;">>> 面试常问问题一</span> </section> <section data-tools="135编辑器" data-id="97272"> <section> <section> <section data-role="outer" label="Powered by 365editor" style="font-family: 微软雅黑;font-size: 16px;"> <blockquote class="js_blockquote_wrap" data-type="2" data-url="" data-author-name="" data-content-utf8-length="76" data-source-title=""> <section class="js_blockquote_digest"> <section> <strong>redis 集群模式的工作原理能说一下么?在集群模式下, redis 的 key 是如何寻址的?分布式寻址都有哪些算法?了解一致性 hash 算法吗?</strong> </section> </section> </blockquote> <p><br></p> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="box-sizing: border-box;font-weight: bolder;letter-spacing: 1px;font-size: 15px;color: rgb(255, 76, 65);">1、面试官心理分析</span> <br> </section> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="letter-spacing: 1px;font-size: 15px;">在前几年,redis 如果要搞几个节点,每个节点存储一部分的数据,得借助一些中间件来实现,比如说有codis,或者 twemproxy,都有。有一些 redis 中间件,你读写 redis 中间件,redis 中间件负责将你的数据分布式存储在多台机器上的 redis 实例中。</span> </section> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="letter-spacing: 1px;font-size: 15px;">这两年,redis 不断在发展,redis 也不断有新的版本,现在的 redis 集群模式,可以做到在多台机器上,部署多个 redis 实例,每个实例存储一部分的数据,同时每个 redis 主实例可以挂 redis 从实例,自动确保说,如果 redis 主实例挂了,会自动切换到 redis 从实例上来。</span> </section> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="letter-spacing: 1px;font-size: 15px;">现在 redis 的新版本,大家都是用 redis cluster 的,也就是 redis 原生支持的 redis 集群模式,那么面试官肯定会就 redis cluster 对你来个几连炮。要是你没用过 redis cluster,正常,以前很多人用 codis 之类的客户端来支持集群,但是起码你得研究一下 redis cluster 吧。</span> </section> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="letter-spacing: 1px;font-size: 15px;">如果你的数据量很少,主要是承载高并发高性能的场景,比如你的缓存一般就几个 G,单机就足够了,可以使用 replication,一个 master 多个 slaves,要几个 slave 跟你要求的读吞吐量有关,然后自己搭建一个 sentinel 集群去保证 redis 主从架构的高可用性。</span> </section> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="letter-spacing: 1px;font-size: 15px;">redis cluster,主要是针对海量数据+高并发+高可用的场景。redis cluster支撑N个 redis master node,每个master node都可以挂载多个slave node。这样整个redis就可以横向扩容了。如果你要支撑更大数据量的缓存,那就横向扩容更多的master节点,每个master节点就能存放更多的数据了。</span> </section> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="color: rgb(255, 76, 65);font-size: 15px;font-weight: bolder;letter-spacing: 1px;">2、面试题剖析</span> <br> </section> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="letter-spacing: 1px;font-size: 15px;">redis cluster 介绍</span> </section> <ul style="margin-bottom: 16px;padding-left: 2em;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);" class="list-paddingleft-2"> <li style="box-sizing: border-box;letter-spacing: 1px;font-size: 15px;"> <section style="text-align: justify;margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="letter-spacing: 1px;font-size: 15px;">自动将数据进行分片,每个 master 上放一部分数据</span> </section></li> <li style="box-sizing: border-box;margin-top: 0.25em;letter-spacing: 1px;font-size: 15px;"> <section style="text-align: justify;margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="letter-spacing: 1px;font-size: 15px;">提供内置的高可用支持,部分 master 不可用时,还是可以继续工作的</span> </section></li> </ul> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="letter-spacing: 1px;font-size: 15px;">在 redis cluster 架构下,每个 redis 要放开两个端口号,比如一个是 6379,另外一个就是 加 1w 的端口号,比如 16379。</span> </section> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="letter-spacing: 1px;font-size: 15px;">16379 端口号是用来进行节点间通信的,也就是 cluster bus 的东西,cluster bus 的通信,用来进行故障检测、配置更新、故障转移授权。cluster bus 用了另外一种二进制的协议,gossip 协议,用于节点间进行高效的数据交换,占用更少的网络带宽和处理时间。</span> </section> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="box-sizing: border-box;font-weight: bolder;letter-spacing: 1px;font-size: 15px;color: rgb(255, 76, 65);">3、节点间的内部通信机制</span> </section> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="box-sizing: border-box;font-weight: bolder;letter-spacing: 1px;font-size: 15px;">1)基本通信原理</span> </section> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="letter-spacing: 1px;font-size: 15px;">集群元数据的维护有两种方式:集中式、Gossip 协议。redis cluster 节点间采用 gossip 协议进行通信。</span> </section> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="letter-spacing: 1px;font-size: 15px;">集中式是将集群元数据(节点信息、故障等等)几种存储在某个节点上。集中式元数据集中存储的一个典型代表,就是大数据领域的 storm。它是分布式的大数据实时计算引擎,是集中式的元数据存储的结构,底层基于 zookeeper(分布式协调的中间件)对所有元数据进行存储维护。</span> </section> <p style="box-sizing: border-box;margin-bottom: 16px;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);"><img src="/upload/b9a257e2c0aae5521c5fdc192b005ca4.png" data-type="png" style="box-sizing: content-box;vertical-align: middle;border-style: none;display: block;margin: 20px auto;border-radius: 0px 0px 5px 5px;object-fit: contain;box-shadow: rgb(132, 161, 168) 0px 5px 5px;" data-ratio="0.5407554671968191" data-w="503"></p> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="letter-spacing: 1px;font-size: 15px;">redis 维护集群元数据采用另一个方式, gossip 协议,所有节点都持有一份元数据,不同的节点如果出现了元数据的变更,就不断将元数据发送给其它的节点,让其它节点也进行元数据的变更。</span> </section> <p style="box-sizing: border-box;margin-bottom: 16px;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);"><img src="/upload/ec88359786508d9738b94e57ef08c1d8.png" data-type="png" style="box-sizing: content-box;vertical-align: middle;border-style: none;display: block;margin: 20px auto;border-radius: 0px 0px 5px 5px;object-fit: contain;box-shadow: rgb(132, 161, 168) 0px 5px 5px;" data-ratio="0.7228381374722838" data-w="451"></p> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="letter-spacing: 1px;font-size: 15px;">集中式的好处在于,元数据的读取和更新,时效性非常好,一旦元数据出现了变更,就立即更新到集中式的存储中,其它节点读取的时候就可以感知到;不好在于,所有的元数据的更新压力全部集中在一个地方,可能会导致元数据的存储有压力。</span> </section> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="letter-spacing: 1px;font-size: 15px;">gossip 好处在于,元数据的更新比较分散,不是集中在一个地方,更新请求会陆陆续续打到所有节点上去更新,降低了压力;不好在于,元数据的更新有延时,可能导致集群中的一些操作会有一些滞后。</span> </section> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="letter-spacing: 1px;font-size: 15px;">10000 端口:每个节点都有一个专门用于节点间通信的端口,就是自己提供服务的端口号+10000,比如7001,那么用于节点间通信的就是 17001 端口。每个节点每隔一段时间都会往另外几个节点发送 ping 消息,同时其它几个节点接收到 ping 之后返回 pong。交换的信息:信息包括故障信息,节点的增加和删除,hash slot 信息等等。</span> </section> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="box-sizing: border-box;font-weight: bolder;letter-spacing: 1px;font-size: 15px;">2)gossip 协议</span> </section> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="letter-spacing: 1px;font-size: 15px;">gossip 协议包含多种消息,包含 ping、pong、meet、fail 等等。</span> </section> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="letter-spacing: 1px;font-size: 15px;"><span style="letter-spacing: 1px;box-sizing: border-box;font-weight: bolder;">meet:</span>某个节点发送 meet 给新加入的节点,让新节点加入集群中,然后新节点就会开始与其它节点进行通信。</span> </section> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="letter-spacing: 1px;font-size: 15px;">redis-trib.rb add-node</span> </section> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="letter-spacing: 1px;font-size: 15px;">其实内部就是发送了一个 gossip meet 消息给新加入的节点,通知那个节点去加入我们的集群。</span> </section> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="letter-spacing: 1px;font-size: 15px;"><span style="letter-spacing: 1px;box-sizing: border-box;font-weight: bolder;">ping:</span>每个节点都会频繁给其它节点发送 ping,其中包含自己的状态还有自己维护的集群元数据,互相通过 ping 交换元数据。</span> </section> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="letter-spacing: 1px;font-size: 15px;"><span style="letter-spacing: 1px;box-sizing: border-box;font-weight: bolder;">pong:</span>返回ping和meeet,包括自己的状态和其他信息,也用于信息广播和更新。fail:某个节点判断另一个节点fail之后,就发送fail给其他节点,通知其他节点说,某个节点宕机啦。</span> </section> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="box-sizing: border-box;font-weight: bolder;letter-spacing: 1px;font-size: 15px;">3)ping 消息深入</span> </section> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="letter-spacing: 1px;font-size: 15px;">ping 时要携带一些元数据,如果很频繁,可能会加重网络负担。</span> </section> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="letter-spacing: 1px;font-size: 15px;">每个节点每秒会执行 10 次 ping,每次会选择 5 个最久没有通信的其它节点。当然如果发现某个节点通信延时达到了 cluster_node_timeout / 2,那么立即发送 ping,避免数据交换延时过长,落后的时间太长了。</span> </section> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="letter-spacing: 1px;font-size: 15px;">比如说,两个节点之间都 10 分钟没有交换数据了,那么整个集群处于严重的元数据不一致的情况,就会有问题。所以 cluster_node_timeout 可以调节,如果调得比较大,那么会降低 ping 的频率。</span> </section> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="letter-spacing: 1px;font-size: 15px;">每次 ping,会带上自己节点的信息,还有就是带上 1/10 其它节点的信息,发送出去,进行交换。至少包含 3 个其它节点的信息,最多包含 总节点数减 2 个其它节点的信息。</span> </section> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="box-sizing: border-box;font-weight: bolder;letter-spacing: 1px;font-size: 15px;">4)分布式寻址算法</span> </section> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="letter-spacing: 1px;font-size: 15px;">hash 算法(大量缓存重建)</span> </section> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="letter-spacing: 1px;font-size: 15px;">一致性 hash 算法(自动缓存迁移)+ 虚拟节点(自动负载均衡)</span> </section> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="letter-spacing: 1px;font-size: 15px;">redis cluster 的 hash slot 算法</span> </section> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="box-sizing: border-box;font-weight: bolder;letter-spacing: 1px;font-size: 15px;">5)hash 算法</span> </section> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="letter-spacing: 1px;font-size: 15px;">来了一个 key,首先计算 hash 值,然后对节点数取模。</span> </section> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="letter-spacing: 1px;font-size: 15px;">然后打在不同的 master 节点上。一旦某一个master 节点宕机,所有请求过来,都会基于最新的剩余 master 节点数去取模,尝试去取数据。</span> </section> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="letter-spacing: 1px;font-size: 15px;">这会导致大部分的请求过来,全部无法拿到有效的缓存,导致大量的流量涌入数据库。</span> </section> <p style="box-sizing: border-box;margin-bottom: 16px;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);"><img src="/upload/ff879902f87a02347cc6f02adcaff4d8.png" data-type="png" style="box-sizing: content-box;vertical-align: middle;border-style: none;display: block;margin: 20px auto;border-radius: 0px 0px 5px 5px;object-fit: contain;box-shadow: rgb(132, 161, 168) 0px 5px 5px;" data-ratio="0.6901098901098901" data-w="455"></p> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="box-sizing: border-box;font-weight: bolder;letter-spacing: 1px;font-size: 15px;">6)一致性 hash 算法</span> </section> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="letter-spacing: 1px;font-size: 15px;">一致性 hash 算法将整个 hash 值空间组织成一个虚拟的圆环,整个空间按顺时针方向组织,下一步将各个 master 节点(使用服务器的 ip 或主机名)进行 hash。这样就能确定每个节点在其哈希环上的位置。</span> </section> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="letter-spacing: 1px;font-size: 15px;">来了一个 key,首先计算 hash 值,并确定此数据在环上的位置,从此位置沿环顺时针“行走”,遇到的第一个 master 节点就是 key 所在位置。</span> </section> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="letter-spacing: 1px;font-size: 15px;">在一致性哈希算法中,如果一个节点挂了,受影响的数据仅仅是此节点到环空间前一个节点(沿着逆时针方向行走遇到的第一个节点)之间的数据,其它不受影响。增加一个节点也同理。</span> </section> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="letter-spacing: 1px;font-size: 15px;">燃鹅,一致性哈希算法在节点太少时,容易因为节点分布不均匀而造成缓存热点的问题。为了解决这种热点问题,一致性 hash 算法引入了虚拟节点机制,即对每一个节点计算多个 hash,每个计算结果位置都放置一个虚拟节点。这样就实现了数据的均匀分布,负载均衡。</span> </section> <p style="box-sizing: border-box;margin-bottom: 16px;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);"><img src="/upload/34ecd89b018b585839d64bcb8cf34077.jpg" data-type="jpeg" style="box-sizing: content-box;vertical-align: middle;border-style: none;display: block;margin: 20px auto;border-radius: 0px 0px 5px 5px;object-fit: contain;box-shadow: rgb(132, 161, 168) 0px 5px 5px;" data-ratio="1.0440613026819923" data-w="522"></p> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="box-sizing: border-box;font-weight: bolder;letter-spacing: 1px;font-size: 15px;">7)redis cluster 的 hash slot 算法</span> </section> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="letter-spacing: 1px;font-size: 15px;">redis cluster 有固定的 16384 个 hash slot,对每个 key 计算 CRC16 值,然后对 16384 取模,可以获取 key 对应的 hash slot。</span> </section> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="letter-spacing: 1px;font-size: 15px;">redis cluster 中每个 master 都会持有部分 slot,比如有 3 个 master,那么可能每个 master 持有5000 多个 hash slot。hash slot 让 node 的增加和移除很简单,增加一个 master,就将其他 master的 hash slot 移动部分过去,减少一个 master,就将它的 hash slot 移动到其他 master 上去。移动hash slot 的成本是非常低的。客户端的 api,可以对指定的数据,让他们走同一个 hash slot,通过 hash tag 来实现。</span> </section> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="letter-spacing: 1px;font-size: 15px;">任何一台机器宕机,另外两个节点,不影响的。因为 key 找的是 hash slot,不是机器。</span> </section> <p style="box-sizing: border-box;margin-bottom: 16px;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);"><img src="/upload/5f54bf462d46ccd7380b4e2bb2fc899d.png" data-type="png" style="box-sizing: content-box;vertical-align: middle;border-style: none;display: block;margin: 20px auto;border-radius: 0px 0px 5px 5px;object-fit: contain;box-shadow: rgb(132, 161, 168) 0px 5px 5px;" data-ratio="0.32857142857142857" data-w="560"></p> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <br> </section> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="box-sizing: border-box;font-weight: bolder;letter-spacing: 1px;font-size: 15px;color: rgb(255, 76, 65);">4、redis cluster 的高可用与主备切换原理</span> </section> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="letter-spacing: 1px;font-size: 15px;">redis cluster 的高可用的原理,几乎跟哨兵是类似的。</span> </section> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="box-sizing: border-box;font-weight: bolder;letter-spacing: 1px;font-size: 15px;">1)判断节点宕机</span> </section> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="letter-spacing: 1px;font-size: 15px;">如果一个节点认为另外一个节点宕机,那么就是 pfail,主观宕机。如果多个节点都认为另外一个节点宕机了,那么就是 fail,客观宕机,跟哨兵的原理几乎一样,sdown,odown。</span> </section> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="letter-spacing: 1px;font-size: 15px;">在 cluster-node-timeout 内,某个节点一直没有返回 pong,那么就被认为 pfail。如果一个节点认为某个节点 pfail 了,那么会在 gossip ping 消息中,ping 给其他节点,如果超过半数的节点都认为 pfail 了,那么就会变成 fail。</span> </section> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="box-sizing: border-box;font-weight: bolder;letter-spacing: 1px;font-size: 15px;">2)从节点过滤</span> </section> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="letter-spacing: 1px;font-size: 15px;">对宕机的 master node,从其所有的 slave node 中,选择一个切换成 master node。检查每个 slave node 与 master node 断开连接的时间,如果超过了 </span> <code style="box-sizing: border-box;font-family: PingFangSC-Light, SFMono-Regular, Consolas, 'Liberation Mono', Menlo, Courier, monospace;color: rgb(232, 62, 140);word-break: break-word;padding: 0.2em 0.4em;background-color: rgb(238, 238, 238);border-radius: 0px 0px 5px 5px;"><span style="letter-spacing: 1px;font-size: 15px;">cluster-node-timeout *cluster-slave-validity-factor</span></code> <span style="letter-spacing: 1px;font-size: 15px;">,那么就没有资格切换成 master。</span> </section> <section style="box-sizing: border-box;color: rgb(36, 41, 46);font-family: Roboto, sans-serif;font-size: 14px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);margin-top: 20px;margin-bottom: 20px;line-height: 1.75em;"> <span style="box-sizing: border-box
作者:微信小助手
<section data-mpa-template="t" mpa-paragraph-type="ignored" style="max-width: 100%;white-space: normal;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);overflow-wrap: break-word !important;box-sizing: border-box !important;" data-mpa-powered-by="yiban.io"> <section data-mpa-template="t" mpa-paragraph-type="ignored" style=""> <section data-mpa-template="t" mpa-paragraph-type="ignored" style="max-width: 100%;letter-spacing: 0.544px;overflow-wrap: break-word !important;box-sizing: border-box !important;"> <section data-mpa-template="t" mpa-paragraph-type="ignored" style="max-width: 100%;letter-spacing: 0.544px;overflow-wrap: break-word !important;box-sizing: border-box !important;"> <section data-mpa-template="t" mpa-paragraph-type="ignored" style="max-width: 100%;letter-spacing: 0.544px;overflow-wrap: break-word !important;box-sizing: border-box !important;"> <section style="white-space: normal;color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, 'PingFang SC', Cambria, Cochin, Georgia, Times, 'Times New Roman', serif;font-size: 16px;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);text-align: center;line-height: 2em;"> <span style="letter-spacing: 0.544px;widows: 1;word-spacing: 2px;caret-color: rgb(51, 51, 51);font-family: Optima-Regular, PingFangTC-light;color: rgb(127, 127, 127);font-size: 14px;line-height: 1.75em;"></span> </section> <p style="max-width: 100%;min-height: 1em;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: center;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;font-size: 12px;color: rgb(120, 114, 119);box-sizing: border-box !important;overflow-wrap: break-word !important;user-select: text !important;">点击上方 "</span><span style="max-width: 100%;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;color: rgb(0, 0, 0);font-size: 12px;box-sizing: border-box !important;overflow-wrap: break-word !important;user-select: text !important;"><strong style="max-width: 100%;color: rgb(62, 62, 62);font-size: 14px;box-sizing: border-box !important;overflow-wrap: break-word !important;user-select: text !important;"><span style="max-width: 100%;letter-spacing: 0.544px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;color: rgb(61, 170, 214);box-sizing: border-box !important;overflow-wrap: break-word !important;user-select: text !important;">zhisheng</span></strong></span><span style="max-width: 100%;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;font-size: 12px;color: rgb(120, 114, 119);box-sizing: border-box !important;overflow-wrap: break-word !important;user-select: text !important;">"关注, <span style="max-width: 100%;letter-spacing: 0.544px;box-sizing: border-box !important;overflow-wrap: break-word !important;user-select: text !important;">星标或置顶一起成长</span></span><span style="max-width: 100%;font-size: 14px;letter-spacing: 0.544px;color: rgb(255, 41, 65);line-height: 22.4px;box-sizing: border-box !important;overflow-wrap: break-word !important;"></span></p> <p style="max-width: 100%;min-height: 1em;font-family: -apple-system-font, system-ui, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;color: rgb(62, 62, 62);font-size: 15px;background-color: rgb(255, 255, 255);text-align: center;box-sizing: border-box !important;overflow-wrap: break-word !important;"><a target="_blank" href="https://mp.weixin.qq.com/mp/appmsgalbum?action=getalbum&album_id=1337172142412169216&__biz=MzIxMTE0ODU5NQ==#wechat_redirect" textvalue="Flink 从入门到精通" tab="innerlink" data-linktype="2" style="color: rgb(120, 172, 254);-webkit-tap-highlight-color: rgba(0, 0, 0, 0);cursor: pointer;max-width: 100%;letter-spacing: 0.544px;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-size: 13px;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;user-select: text !important;"><span style="max-width: 100%;letter-spacing: 0.544px;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;user-select: text !important;">Flink 从入门到精通</span></a><span style="max-width: 100%;letter-spacing: 0.544px;color: rgb(136, 136, 136);font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-size: 13px;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;user-select: text !important;"> 系列文章</span></p> <p style="white-space: normal;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);color: rgb(62, 62, 62);font-size: 15px;word-spacing: 1px;font-family: -apple-system-font, system-ui, 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif;text-align: center;"><span style="color: rgb(136, 136, 136);font-family: Optima-Regular, PingFangTC-light;font-size: 14px;"></span><br></p> </section> </section> </section> </section> </section> <section data-tool="mdnice编辑器" data-website="https://www.mdnice.com" style="max-width: 100%;white-space: normal;overflow-wrap: break-word !important;box-sizing: border-box !important;"> <p style="margin: 5px 8px;max-width: 100%;min-height: 1em;font-size: inherit;text-align: right;overflow-wrap: break-word !important;box-sizing: border-box !important;line-height: 1.6 !important;"><span style="font-size: 14px;font-family: Optima-Regular, PingFangTC-light;color: rgb(136, 136, 136);">toutiao.com/i6843391272229536267</span></p> </section> <p style="margin-left: 8px;margin-right: 8px;line-height: 2em;"><span style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;">目录<br></span></p> <article data-v-e1fd63b2=""> <ul class="list-paddingleft-2" style="margin-left: 8px;margin-right: 8px;"> <li style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;"> <section style="line-height: 2em;margin-top: 5px;margin-bottom: 5px;"> <span style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;">docker介绍</span> </section></li> <li style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;"> <section style="line-height: 2em;margin-top: 5px;margin-bottom: 5px;"> <span style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;">安装docker</span> </section></li> <ul class="list-paddingleft-2" style="list-style-type: square;"> <li style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;"> <section style="line-height: 2em;margin-top: 5px;margin-bottom: 5px;"> <span style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;">Ubuntu安装docker</span> </section></li> <li style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;"> <section style="line-height: 2em;margin-top: 5px;margin-bottom: 5px;"> <span style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;">CentOS安装docker</span> </section></li> <li style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;"> <section style="line-height: 2em;margin-top: 5px;margin-bottom: 5px;"> <span style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;">通过脚本安装</span> </section></li> </ul> <li style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;"> <section style="line-height: 2em;margin-top: 5px;margin-bottom: 5px;"> <span style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;">拉取java环境</span> </section></li> <li style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;"> <section style="line-height: 2em;margin-top: 5px;margin-bottom: 5px;"> <span style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;">创建springboot项目</span> </section></li> <li style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;"> <section style="line-height: 2em;margin-top: 5px;margin-bottom: 5px;"> <span style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;">打包springboot到docker</span> </section></li> <li style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;"> <section style="line-height: 2em;margin-top: 5px;margin-bottom: 5px;"> <span style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;">docker查看容器的日志</span> </section></li> <li style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;"> <section style="line-height: 2em;margin-top: 5px;margin-bottom: 5px;"> <span style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;">查看log4j2输出问文件日志</span> </section></li> </ul> <section style="font-size: 16px;color: rgb(51, 51, 51);font-weight: 400;margin: 20px 8px;line-height: 2em;"> <span style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;">Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。</span> </section> <section style="font-size: 16px;color: rgb(51, 51, 51);font-weight: 400;margin: 20px 8px;line-height: 2em;"> <span style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;">docker的核心思想是通过对应用的封装、分发、部署、运行生命周期进行管理,达到应用组件级别的“一次性封装,到处运行”。这里的应用组件,可以是一个web应用,也可以是一个环境,更可以是一个数据库等等。</span> </section> <section style="font-size: 16px;color: rgb(51, 51, 51);font-weight: 400;margin: 20px 8px;line-height: 2em;"> <span style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;">既然docker这么神奇,那我们如何安装docker呢?我们一起来走一下吧。</span> </section> <section style="font-size: 16px;color: rgb(51, 51, 51);font-weight: 400;margin: 20px 8px;line-height: 2em;"> <span style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;">PS:我把 Dorcker 相关的文章整理好了,关注微信公众号 Java后端,回复 666 下载就可以了。</span> </section> <h2 style="margin-left: 8px;margin-right: 8px;line-height: 2em;"><strong><span style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;">Ubuntu安装docker</span></strong></h2> <section style="font-size: 16px;color: rgb(51, 51, 51);font-weight: 400;margin: 20px 8px;line-height: 2em;"> <span style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;">由于本人的系统是CentOS,所以这里就只展示一下CentOS的安装方式,Ubuntu以及其他系统请自行百度。</span> </section> <h2 style="margin-left: 8px;margin-right: 8px;line-height: 2em;"><strong><span style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;">CentOS安装docker</span></strong></h2> <section style="font-size: 16px;color: rgb(51, 51, 51);font-weight: 400;margin: 20px 8px;line-height: 2em;"> <span style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;">docker要求CentOS在7.0以后的版本,如果你的系统版本还在7.0以前,请先升级一下版本在进行安装,同时不支持32位的系统,内核版本至少3.10。</span> </section> <section style="font-size: 16px;color: rgb(51, 51, 51);font-weight: 400;margin: 20px 8px;line-height: 2em;"> <span style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;">请先确保没有安装过docker,否则有可能会导致安装失败,如果之前安装过,可以尝试直接yum isntall -y docker</span> </section> <section style="font-size: 16px;color: rgb(51, 51, 51);font-weight: 400;margin: 20px 8px;line-height: 2em;"> <span style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;"><strong>1.更新软件源</strong>第一个命令</span> </section> <section data-mpa-preserve-tpl-color="t" data-mpa-template="t" mpa-preserve="t" mpa-from-tpl="t"> <pre style="margin:0;padding:0;border-radius:none;background:none;"><code style="border-radius: 4px;font-size: 0.85em;margin: 0px 0.15em;background: rgb(248, 248, 248);color: rgb(51, 51, 51);display: block;padding: 5.95px;overflow-x: auto;white-space: nowrap;"><span style="font-size: 13px;">yum <span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 43px;text-decoration: none solid rgb(51, 51, 51);font-weight: 700;font-style: normal;">update</span></span></code></pre> </section> <p style="font-size: 16px;line-height: 1.7;color: rgb(51, 51, 51);font-weight: 400;margin: 20px 0px;"><img data-ratio="0.16234887737478412" data-w="579" height="94" src="/upload/4f90ef12d2a70cec5b6075f867775e33.null" style="max-width: 100%;display: block;margin: 20px auto 30px;" width="579"></p> <section style="font-size: 16px;color: rgb(51, 51, 51);font-weight: 400;margin: 20px 8px;line-height: 2em;"> <span style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;">遇到他输入y,然后回车,看到下面信息表示更新成功:</span> </section> <p style="font-size: 16px;line-height: 1.7;color: rgb(51, 51, 51);font-weight: 400;margin: 20px 0px;"><img data-ratio="0.3546875" data-w="640" height="358" src="/upload/36c58b43bb67b5c1b034fa67c266db9d.null" style="max-width: 100%;display: block;margin: 20px auto 30px;" width="1010"></p> <section style="font-size: 16px;color: rgb(51, 51, 51);font-weight: 400;margin: 20px 8px;line-height: 2em;"> <span style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;">第二个命令</span> </section> <section data-mpa-preserve-tpl-color="t" data-mpa-template="t" mpa-preserve="t" mpa-from-tpl="t"> <pre style="margin:0;padding:0;border-radius:none;background:none;"><code style="border-radius: 4px;font-size: 0.85em;margin: 0px 0.15em;background: rgb(248, 248, 248);color: rgb(51, 51, 51);display: block;padding: 5.95px;overflow-x: auto;white-space: nowrap;"><span style="font-size: 13px;">yum <span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 50px;text-decoration: none solid rgb(51, 51, 51);font-weight: 700;font-style: normal;">install</span> -y yum-utils device-mapper-persistent-<span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 29px;text-decoration: none solid rgb(51, 51, 51);font-weight: 700;font-style: normal;">data</span> lvm2</span></code></pre> </section> <p style="font-size: 16px;line-height: 1.7;color: rgb(51, 51, 51);font-weight: 400;margin: 20px 0px;"><img data-ratio="0.3314285714285714" data-w="1050" height="348" src="/upload/df028b4480da45794b54637bde8adba8.null" style="max-width: 100%;display: block;margin: 20px auto 30px;" width="1050"></p> <section style="font-size: 16px;color: rgb(51, 51, 51);font-weight: 400;margin: 20px 8px;line-height: 2em;"> <span style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;"><strong>2.添加docker稳定版本的yum软件源</strong></span> </section> <pre> <section data-mpa-preserve-tpl-color="t" data-mpa-template="t" mpa-preserve="t" mpa-from-tpl="t"> <pre style="margin:0;padding:0;border-radius:none;background:none;"><code style="border-radius: 4px;font-size: 0.85em;margin: 0px 0.15em;background: rgb(248, 248, 248);color: rgb(51, 51, 51);display: block;padding: 5.95px;overflow-x: auto;white-space: nowrap;"><span style="font-size: 13px;">yum-config-manager --<span style="font-size: 13px;color: rgb(0, 134, 179);background: rgba(0, 0, 0, 0);display: inline;width: 22px;text-decoration: none solid rgb(0, 134, 179);font-weight: 400;font-style: normal;">add</span>-repo http<span style="font-size: 13px;color: rgb(0, 128, 128);background: rgba(0, 0, 0, 0);display: inline;width: 15px;text-decoration: none solid rgb(0, 128, 128);font-weight: 400;font-style: normal;">s:</span>//download.docker.<span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 22px;text-decoration: none solid rgb(51, 51, 51);font-weight: 700;font-style: normal;">com</span>/linux/centos/docker-<span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 15px;text-decoration: none solid rgb(51, 51, 51);font-weight: 700;font-style: normal;">ce</span>.repo</span></code></pre> </section></pre> <p style="font-size: 16px;line-height: 1.7;color: rgb(51, 51, 51);font-weight: 400;margin: 20px 0px;"><img data-ratio="0.12350119904076738" data-w="834" height="103" src="/upload/667fbed9ede6dfb2cc6bfd23ed39cd09.null" style="max-width: 100%;display: block;margin: 20px auto 30px;" width="834"></p> <section style="font-size: 16px;color: rgb(51, 51, 51);font-weight: 400;margin: 20px 8px;line-height: 2em;"> <span style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;"><strong>3.再次更新yum源,并安装docker</strong></span> </section> <pre> <section data-mpa-preserve-tpl-color="t" data-mpa-template="t" mpa-preserve="t" mpa-from-tpl="t"> <pre style="margin:0;padding:0;border-radius:none;background:none;"><code style="border-radius: 4px;font-size: 0.85em;margin: 0px 0.15em;background: rgb(248, 248, 248);color: rgb(51, 51, 51);display: block;padding: 5.95px;overflow-x: auto;white-space: nowrap;"><span style="font-size: 13px;">yum <span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 43px;text-decoration: none solid rgb(51, 51, 51);font-weight: 700;font-style: normal;">update</span></span></code></pre> </section></pre> <p style="font-size: 16px;line-height: 1.7;color: rgb(51, 51, 51);font-weight: 400;margin: 20px 0px;"><img data-ratio="0.18421052631578946" data-w="950" height="175" src="/upload/3eb919690d158bdd979349c4b781929c.null" style="max-width: 100%;display: block;margin: 20px auto 30px;" width="950"></p> <pre> <section data-mpa-preserve-tpl-color="t" data-mpa-template="t" mpa-preserve="t" mpa-from-tpl="t"> <pre style="margin:0;padding:0;border-radius:none;background:none;"><code style="border-radius: 4px;font-size: 0.85em;margin: 0px 0.15em;background: rgb(248, 248, 248);color: rgb(51, 51, 51);display: block;padding: 5.95px;overflow-x: auto;white-space: nowrap;"><span style="font-size: 13px;">yum <span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 50px;text-decoration: none solid rgb(51, 51, 51);font-weight: 700;font-style: normal;">install</span> -y docker-ce</span></code></pre> </section></pre> <p style="font-size: 16px;line-height: 1.7;color: rgb(51, 51, 51);font-weight: 400;margin: 20px 0px;"><img data-ratio="0.19473684210526315" data-w="950" height="185" src="/upload/b9892cb9743448d7bae642ae1399cbd1.null" style="max-width: 100%;display: block;margin: 20px auto 30px;" width="950"></p> <section style="font-size: 16px;color: rgb(51, 51, 51);font-weight: 400;margin: 20px 8px;line-height: 2em;"> <span style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;">看到这个页面,标识docker已经安装成功了。</span> </section> <section style="font-size: 16px;color: rgb(51, 51, 51);font-weight: 400;margin: 20px 8px;line-height: 2em;"> <span style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;"><strong>4.安装完成之后启动docker</strong></span> </section> <section data-mpa-preserve-tpl-color="t" data-mpa-template="t" mpa-preserve="t" mpa-from-tpl="t"> <pre style="margin:0;padding:0;border-radius:none;background:none;"><code style="border-radius: 4px;font-size: 0.85em;margin: 0px 0.15em;background: rgb(248, 248, 248);color: rgb(51, 51, 51);display: block;padding: 5.95px;overflow-x: auto;white-space: nowrap;"><span style="font-size: 13px;">systemctl <span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 36px;text-decoration: none solid rgb(51, 51, 51);font-weight: 700;font-style: normal;">start</span> docker</span></code></pre> </section> <section style="font-size: 16px;color: rgb(51, 51, 51);font-weight: 400;margin: 20px 8px;line-height: 2em;"> <span style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;"><strong>5.重启</strong></span> </section> <section data-mpa-preserve-tpl-color="t" data-mpa-template="t" mpa-preserve="t" mpa-from-tpl="t"> <pre style="margin:0;padding:0;border-radius:none;background:none;"><code style="border-radius: 4px;font-size: 0.85em;margin: 0px 0.15em;background: rgb(248, 248, 248);color: rgb(51, 51, 51);display: block;padding: 5.95px;overflow-x: auto;white-space: nowrap;"><span style="font-size: 13px;"><span style="font-size: 13px;color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 65px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;">systemctl</span> restart docker</span></code></pre> </section> <section style="font-size: 16px;color: rgb(51, 51, 51);font-weight: 400;margin: 20px 8px;line-height: 2em;"> <span style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;"><strong>6.停止</strong></span> </section> <section data-mpa-preserve-tpl-color="t" data-mpa-template="t" mpa-preserve="t" mpa-from-tpl="t"> <pre style="margin:0;padding:0;border-radius:none;background:none;"><code style="border-radius: 4px;font-size: 0.85em;margin: 0px 0.15em;background: rgb(248, 248, 248);color: rgb(51, 51, 51);display: block;padding: 5.95px;overflow-x: auto;white-space: nowrap;"><span style="font-size: 13px;">systemctl <span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 29px;text-decoration: none solid rgb(51, 51, 51);font-weight: 700;font-style: normal;">stop</span> docker</span></code></pre> </section> <section style="font-size: 16px;color: rgb(51, 51, 51);font-weight: 400;margin: 20px 8px;line-height: 2em;"> <span style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;"><strong>7.开机自启动</strong></span> </section> <section data-mpa-preserve-tpl-color="t" data-mpa-template="t" mpa-preserve="t" mpa-from-tpl="t"> <pre style="margin:0;padding:0;border-radius:none;background:none;"><code style="border-radius: 4px;font-size: 0.85em;margin: 0px 0.15em;background: rgb(248, 248, 248);color: rgb(51, 51, 51);display: block;padding: 5.95px;overflow-x: auto;white-space: nowrap;"><span style="font-size: 13px;">systemctl <span style="font-size: 13px;color: rgb(0, 134, 179);background: rgba(0, 0, 0, 0);display: inline;width: 43px;text-decoration: none solid rgb(0, 134, 179);font-weight: 400;font-style: normal;">enable</span> docker</span></code></pre> </section> <section style="font-size: 16px;color: rgb(51, 51, 51);font-weight: 400;margin: 20px 8px;line-height: 2em;"> <span style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;"><strong>8.查看docker的状态</strong></span> </section> <section data-mpa-preserve-tpl-color="t" data-mpa-template="t" mpa-preserve="t" mpa-from-tpl="t"> <pre style="margin:0;padding:0;border-radius:none;background:none;"><code style="border-radius: 4px;font-size: 0.85em;margin: 0px 0.15em;background: rgb(248, 248, 248);color: rgb(51, 51, 51);display: block;padding: 5.95px;overflow-x: auto;white-space: nowrap;"><span style="font-size: 13px;"><span style="font-size: 13px;color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 65px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;">systemctl</span> status docker</span></code></pre> </section> <h2 style="margin-left: 8px;margin-right: 8px;line-height: 2em;margin-top: 15px;"><span style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;">通过脚本安装</span></h2> <section style="font-size: 16px;color: rgb(51, 51, 51);font-weight: 400;margin: 20px 8px;line-height: 2em;"> <span style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;">除了上面的yum安装,还可以采用shell脚本安装,安装流程如下:</span> </section> <section data-mpa-preserve-tpl-color="t" data-mpa-template="t" mpa-preserve="t" mpa-from-tpl="t"> <pre style="margin:0;padding:0;border-radius:none;background:none;"><code style="border-radius: 4px;font-size: 0.85em;margin: 0px 0.15em;background: rgb(248, 248, 248);color: rgb(51, 51, 51);display: block;padding: 5.95px;overflow-x: auto;white-space: nowrap;"><span style="font-size: 13px;">curl -fsSL http<span style="font-size: 13px;color: rgb(0, 128, 128);background: rgba(0, 0, 0, 0);display: inline;width: 15px;text-decoration: none solid rgb(0, 128, 128);font-weight: 400;font-style: normal;">s:</span>//<span style="font-size: 13px;color: rgb(0, 134, 179);background: rgba(0, 0, 0, 0);display: inline;width: 22px;text-decoration: none solid rgb(0, 134, 179);font-weight: 400;font-style: normal;">get</span>.docker.<span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 22px;text-decoration: none solid rgb(51, 51, 51);font-weight: 700;font-style: normal;">com</span>/ | <span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 15px;text-decoration: none solid rgb(51, 51, 51);font-weight: 700;font-style: normal;">sh</span></span></code></pre> </section> <section style="font-size: 16px;color: rgb(51, 51, 51);font-weight: 400;margin: 20px 8px;line-height: 2em;"> <span style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;">或者</span> </section> <section data-mpa-preserve-tpl-color="t" data-mpa-template="t" mpa-preserve="t" mpa-from-tpl="t"> <pre style="margin:0;padding:0;border-radius:none;background:none;"><code style="border-radius: 4px;font-size: 0.85em;margin: 0px 0.15em;background: rgb(248, 248, 248);color: rgb(51, 51, 51);display: block;padding: 5.95px;overflow-x: auto;white-space: nowrap;"><span style="font-size: 13px;">wget -qO- http<span style="font-size: 13px;color: rgb(0, 128, 128);background: rgba(0, 0, 0, 0);display: inline;width: 14px;text-decoration: none solid rgb(0, 128, 128);font-weight: 400;font-style: normal;">s:</span>//<span style="font-size: 13px;color: rgb(0, 134, 179);background: rgba(0, 0, 0, 0);display: inline;width: 21px;text-decoration: none solid rgb(0, 134, 179);font-weight: 400;font-style: normal;">get</span>.docker.<span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 22px;text-decoration: none solid rgb(51, 51, 51);font-weight: 700;font-style: normal;">com</span>/ | <span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 14px;text-decoration: none solid rgb(51, 51, 51);font-weight: 700;font-style: normal;">sh</span></span></code></pre> </section> <section style="font-size: 16px;color: rgb(51, 51, 51);font-weight: 400;margin: 20px 8px;line-height: 2em;"> <span style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;">拉取jdk很简单,直接执行一行代码即可,我这里拉取的时java 8的版本。</span> </section> <section data-mpa-preserve-tpl-color="t" data-mpa-template="t" mpa-preserve="t" mpa-from-tpl="t"> <pre style="margin:0;padding:0;border-radius:none;background:none;"><code style="border-radius: 4px;font-size: 0.85em;margin: 0px 0.15em;background: rgb(248, 248, 248);color: rgb(51, 51, 51);display: block;padding: 5.95px;overflow-x: auto;white-space: nowrap;"><span style="font-size: 13px;">docker pull jav<span style="font-size: 13px;color: rgb(0, 128, 128);background: rgba(0, 0, 0, 0);display: inline;width: 22px;text-decoration: none solid rgb(0, 128, 128);font-weight: 400;font-style: normal;">a:8</span></span></code></pre> </section> <section style="font-size: 16px;color: rgb(51, 51, 51);font-weight: 400;margin: 20px 8px;line-height: 2em;"> <span style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;">拉取完成之后执行:</span> </section> <section data-mpa-preserve-tpl-color="t" data-mpa-template="t" mpa-preserve="t" mpa-from-tpl="t"> <pre style="margin:0;padding:0;border-radius:none;background:none;"><code style="border-radius: 4px;font-size: 0.85em;margin: 0px 0.15em;background: rgb(248, 248, 248);color: rgb(51, 51, 51);display: block;padding: 5.95px;overflow-x: auto;white-space: nowrap;"><span style="font-size: 13px;"><span style="font-size: 13px;color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 43px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;">docker</span> images</span></code></pre> </section> <section style="font-size: 16px;color: rgb(51, 51, 51);font-weight: 400;margin: 20px 8px;line-height: 2em;"> <span style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;">如果出现下面内容,表示拉取成功</span> </section> <p style="font-size: 16px;line-height: 1.7;color: rgb(51, 51, 51);font-weight: 400;margin: 20px 0px;"><img data-ratio="0.11833550065019506" data-w="769" height="91" src="/upload/9270be2db687cc952d4b089c4ac94bab.null" style="max-width: 100%;display: block;margin: 20px auto 30px;" width="769"></p> <section style="font-size: 16px;color: rgb(51, 51, 51);font-weight: 400;margin: 20px 8px;line-height: 2em;"> <span style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;"><strong>1.新建项目</strong></span> </section> <p style="font-size: 16px;line-height: 1.7;color: rgb(51, 51, 51);font-weight: 400;margin: 20px 0px;"><img data-ratio="0.6796875" data-w="640" height="557" src="/upload/37c81841345c56ef254849ba39483576.null" style="max-width: 100%;display: block;margin: 20px auto 30px;" width="819"></p> <section style="font-size: 16px;color: rgb(51, 51, 51);font-weight: 400;margin: 20px 8px;line-height: 2em;"> <span style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;">引入sprint-boot-web的依赖</span> </section> <p style="font-size: 16px;line-height: 1.7;color: rgb(51, 51, 51);font-weight: 400;margin: 20px 0px;"><img data-ratio="0.678125" data-w="640" height="555" src="/upload/3f1e4f40aba98a56c3efccb8714d9b2e.null" style="max-width: 100%;display: block;margin: 20px auto 30px;" width="819"></p> <section style="font-size: 16px;color: rgb(51, 51, 51);font-weight: 400;margin: 20px 8px;line-height: 2em;"> <span style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;">新建完成之后的项目结构</span> </section> <p style="font-size: 16px;line-height: 1.7;color: rgb(51, 51, 51);font-weight: 400;margin: 20px 0px;"><img data-ratio="0.5551601423487544" data-w="281" height="156" src="/upload/556a412136adfcc0ef972b05cbb00494.null" style="max-width: 100%;display: block;margin: 20px auto 30px;" width="281"></p> <section style="font-size: 16px;color: rgb(51, 51, 51);font-weight: 400;margin: 20px 8px;line-height: 2em;"> <span style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;"><strong>2.引入docker依赖</strong></span> </section> <section data-mpa-preserve-tpl-color="t" data-mpa-template="t" mpa-preserve="t" mpa-from-tpl="t"> <pre style="margin:0;padding:0;border-radius:none;background:none;"><code style="border-radius: 4px;font-size: 0.85em;margin: 0px 0.15em;background: rgb(248, 248, 248);color: rgb(51, 51, 51);display: block;padding: 5.95px;overflow-x: auto;white-space: nowrap;"><span style="font-size: 13px;"><span style="font-size: 13px;color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 86px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;"><<span style="color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 72px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;">properties</span>></span><br mpa-from-tpl="t"> <span style="font-size: 13px;color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 152px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;"><<span style="color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 137px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;">docker.image.prefix</span>></span>registry.aliyuncs.com/linhuatest<span style="font-size: 13px;color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 159px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;"></<span style="color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 137px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;">docker.image.prefix</span>></span><br mpa-from-tpl="t"> <span style="font-size: 13px;color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 94px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;"></<span style="color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 72px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;">properties</span>></span><br mpa-from-tpl="t"><br mpa-from-tpl="t"><br mpa-from-tpl="t"> <span style="font-size: 13px;color: rgb(153, 153, 136);background: rgba(0, 0, 0, 0);display: inline;width: 132px;text-decoration: none solid rgb(153, 153, 136);font-weight: 400;font-style: italic;"><!-- docker插件 --></span><br mpa-from-tpl="t"> <span style="font-size: 13px;color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 58px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;"><<span style="color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 43px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;">plugin</span>></span><br mpa-from-tpl="t"> <span style="font-size: 13px;color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 65px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;"><<span style="color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 50px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;">groupId</span>></span>com.spotify<span style="font-size: 13px;color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 72px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;"></<span style="color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 51px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;">groupId</span>></span><br mpa-from-tpl="t"> <span style="font-size: 13px;color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 87px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;"><<span style="color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 72px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;">artifactId</span>></span>docker-maven-plugin<span style="font-size: 13px;color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 94px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;"></<span style="color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 72px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;">artifactId</span>></span><br mpa-from-tpl="t"> <span style="font-size: 13px;color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 65px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;"><<span style="color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 50px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;">version</span>></span>1.0.0<span style="font-size: 13px;color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 73px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;"></<span style="color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 51px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;">version</span>></span><br mpa-from-tpl="t"> <span style="font-size: 13px;color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 109px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;"><<span style="color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 93px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;">configuration</span>></span><br mpa-from-tpl="t"> <span style="font-size: 13px;color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 80px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;"><<span style="color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 65px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;">imageName</span>></span>${docker.image.prefix}/${project.artifactId}<span style="font-size: 13px;color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 86px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;"></<span style="color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 65px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;">imageName</span>></span><br mpa-from-tpl="t"> <span style="font-size: 13px;color: rgb(153, 153, 136);background: rgba(0, 0, 0, 0);display: inline;width: 178px;text-decoration: none solid rgb(153, 153, 136);font-weight: 400;font-style: italic;"><!--docker文件所在的目录--></span><br mpa-from-tpl="t"> <span style="font-size: 13px;color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 123px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;"><<span style="color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 109px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;">dockerDirectory</span>></span>src/main/docker<span style="font-size: 13px;color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 131px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;"></<span style="color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 108px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;">dockerDirectory</span>></span><br mpa-from-tpl="t"> <span style="font-size: 13px;color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 80px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;"><<span style="color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 65px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;">resources</span>></span><br mpa-from-tpl="t"> <span style="font-size: 13px;color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 72px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;"><<span style="color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 58px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;">resource</span>></span><br mpa-from-tpl="t"> <span style="font-size: 13px;color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 87px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;"><<span style="color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 73px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;">targetPath</span>></span>/<span style="font-size: 13px;color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 94px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;"></<span style="color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 73px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;">targetPath</span>></span><br mpa-from-tpl="t"> <span style="font-size: 13px;color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 80px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;"><<span style="color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 65px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;">directory</span>></span>${project.build.directory}<span style="font-size: 13px;color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 87px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;"></<span style="color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 65px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;">directory</span>></span><br mpa-from-tpl="t"> <span style="font-size: 13px;color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 65px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;"><<span style="color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 51px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;">include</span>></span>${project.build.finalName}.jar<span style="font-size: 13px;color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 72px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;"></<span style="color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 51px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;">include</span>></span><br mpa-from-tpl="t"> <span style="font-size: 13px;color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 80px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;"></<span style="color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 57px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;">resource</span>></span><br mpa-from-tpl="t"> <span style="font-size: 13px;color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 87px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;"></<span style="color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 65px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;">resources</span>></span><br mpa-from-tpl="t"> <span style="font-size: 13px;color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 116px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;"></<span style="color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 94px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;">configuration</span>></span><br mpa-from-tpl="t"> <span style="font-size: 13px;color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 65px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;"></<span style="font-size: 13px;color: rgb(0, 0, 128);background: rgba(0, 0, 0, 0);display: inline;width: 43px;text-decoration: none solid rgb(0, 0, 128);font-weight: 400;font-style: normal;">plugin</span>></span></span></code></pre> </section> <section style="font-size: 16px;color: rgb(51, 51, 51);font-weight: 400;margin: 20px 8px;line-height: 2em;"> <span style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;"><strong>3.新建docker文件</strong>在main目录下新建docker目录,然后在docker目录下创建dockerfile文件,不需要后缀名。</span> <br> </section> <p style="font-size: 16px;line-height: 1.7;color: rgb(51, 51, 51);font-weight: 400;margin: 20px 0px;"><img data-ratio="0.7543186180422264" data-w="521" height="393" src="/upload/3b7d156aa5929b001caaab713f41551f.null" style="max-width: 100%;display: block;margin: 20px auto 30px;" width="521"></p> <section style="font-size: 16px;color: rgb(51, 51, 51);font-weight: 400;margin: 20px 8px;line-height: 2em;"> <span style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;">创建完成之后的工程目录如下:</span> </section> <p style="font-size: 16px;line-height: 1.7;color: rgb(51, 51, 51);font-weight: 400;margin: 20px 0px;"><img data-ratio="0.648068669527897" data-w="466" height="302" src="/upload/d7fea4a4b0412368161b391a87cc6415.null" style="max-width: 100%;display: block;margin: 20px auto 30px;" width="466"></p> <section style="font-size: 16px;color: rgb(51, 51, 51);font-weight: 400;margin: 20px 8px;line-height: 2em;"> <span style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;"><strong>4.编辑dockerfile文件</strong></span> </section> <section data-mpa-preserve-tpl-color="t" data-mpa-template="t" mpa-preserve="t" mpa-from-tpl="t"> <pre style="margin:0;padding:0;border-radius:none;background:none;"><code style="border-radius: 4px;font-size: 0.85em;margin: 0px 0.15em;background: rgb(248, 248, 248);color: rgb(51, 51, 51);display: block;padding: 5.95px;overflow-x: auto;white-space: nowrap;"><span style="font-size: 13px;">FROM jav<span style="font-size: 13px;color: rgb(0, 128, 128);background: rgba(0, 0, 0, 0);display: inline;width: 21px;text-decoration: none solid rgb(0, 128, 128);font-weight: 400;font-style: normal;">a:8</span><br mpa-from-tpl="t">VOLUME /tmp/tomcat<br mpa-from-tpl="t">ADD spring-boot-docker-<span style="font-size: 13px;color: rgb(0, 128, 128);background: rgba(0, 0, 0, 0);display: inline;width: 22px;text-decoration: none solid rgb(0, 128, 128);font-weight: 400;font-style: normal;">0.0</span>.<span style="font-size: 13px;color: rgb(0, 128, 128);background: rgba(0, 0, 0, 0);display: inline;width: 7px;text-decoration: none solid rgb(0, 128, 128);font-weight: 400;font-style: normal;">1</span>-SNAPSHOT.jar springboot-docker.jar<br mpa-from-tpl="t">ENTRYPOINT [<span style="font-size: 13px;color: rgb(221, 17, 68);background: rgba(0, 0, 0, 0);display: inline;width: 44px;text-decoration: none solid rgb(221, 17, 68);font-weight: 400;font-style: normal;">"java"</span>,<span style="font-size: 13px;color: rgb(221, 17, 68);background: rgba(0, 0, 0, 0);display: inline;width: 296px;text-decoration: none solid rgb(221, 17, 68);font-weight: 400;font-style: normal;">"-Djava.security.egd=file:/dev/./urandom"</span>,<span style="font-size: 13px;color: rgb(221, 17, 68);background: rgba(0, 0, 0, 0);display: inline;width: 44px;text-decoration: none solid rgb(221, 17, 68);font-weight: 400;font-style: normal;">"-jar"</span>,<span style="font-size: 13px;color: rgb(221, 17, 68);background: rgba(0, 0, 0, 0);display: inline;width: 173px;text-decoration: none solid rgb(221, 17, 68);font-weight: 400;font-style: normal;">"/springboot-docker.jar"</span>]</span></code></pre> </section> <blockquote> <section style="font-size: 16px;color: rgb(51, 51, 51);font-weight: 400;margin: 20px 8px;line-height: 2em;"> <span style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;">FROM:指定存在的镜像,java:8是我刚刚拉取的镜像,运行的基础。VOLUME:指向的一个临时文件,用于存储tomcat工作。ADD:复制文件并且重命名文件。ENTRYPOINT:初始化配置或者自定义配置。</span> </section> </blockquote> <section style="font-size: 16px;color: rgb(51, 51, 51);font-weight: 400;margin: 20px 8px;line-height: 2em;"> <span style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;"><strong>5.创建测试接口</strong></span> </section> <p style="font-size: 16px;line-height: 1.7;color: rgb(51, 51, 51);font-weight: 400;margin: 20px 0px;"><img data-ratio="0.25513196480938416" data-w="341" height="87" src="/upload/d20079d5a84cda9ac381ffb5cadae78d.null" style="max-width: 100%;display: block;margin: 20px auto 30px;" width="341"></p> <section style="font-size: 16px;color: rgb(51, 51, 51);font-weight: 400;margin: 20px 8px;line-height: 2em;"> <span style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;">TestController内容如下:</span> </section> <section data-mpa-preserve-tpl-color="t" data-mpa-template="t" mpa-preserve="t" mpa-from-tpl="t"> <pre style="margin:0;padding:0;border-radius:none;background:none;"><code style="border-radius: 4px;font-size: 0.85em;margin: 0px 0.15em;background: rgb(248, 248, 248);color: rgb(51, 51, 51);display: block;padding: 5.95px;overflow-x: auto;white-space: nowrap;"><span style="font-size: 13px;"><span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 50px;text-decoration: none solid rgb(51, 51, 51);font-weight: 700;font-style: normal;">package</span> <span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 21px;text-decoration: none solid rgb(51, 51, 51);font-weight: 700;font-style: normal;">com</span><span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 29px;text-decoration: none solid rgb(51, 51, 51);font-weight: 400;font-style: normal;">.ymy</span><span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 80px;text-decoration: none solid rgb(51, 51, 51);font-weight: 400;font-style: normal;">.controller</span>;<br mpa-from-tpl="t"><br mpa-from-tpl="t"><span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 43px;text-decoration: none solid rgb(51, 51, 51);font-weight: 700;font-style: normal;">import</span> <span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 44px;text-decoration: none solid rgb(51, 51, 51);font-weight: 700;font-style: normal;">lombok</span><span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 50px;text-decoration: none solid rgb(51, 51, 51);font-weight: 400;font-style: normal;">.extern</span><span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 44px;text-decoration: none solid rgb(51, 51, 51);font-weight: 400;font-style: normal;">.slf4j</span><span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 43px;text-decoration: none solid rgb(51, 51, 51);font-weight: 400;font-style: normal;">.Slf4j</span>;<br mpa-from-tpl="t"><span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 43px;text-decoration: none solid rgb(51, 51, 51);font-weight: 700;font-style: normal;">import</span> <span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 22px;text-decoration: none solid rgb(51, 51, 51);font-weight: 700;font-style: normal;">org</span><span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 116px;text-decoration: none solid rgb(51, 51, 51);font-weight: 400;font-style: normal;">.springframework</span><span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 29px;text-decoration: none solid rgb(51, 51, 51);font-weight: 400;font-style: normal;">.web</span><span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 36px;text-decoration: none solid rgb(51, 51, 51);font-weight: 400;font-style: normal;">.bind</span><span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 79px;text-decoration: none solid rgb(51, 51, 51);font-weight: 400;font-style: normal;">.annotation</span><span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 108px;text-decoration: none solid rgb(51, 51, 51);font-weight: 400;font-style: normal;">.RequestMapping</span>;<br mpa-from-tpl="t"><span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 43px;text-decoration: none solid rgb(51, 51, 51);font-weight: 700;font-style: normal;">import</span> <span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 22px;text-decoration: none solid rgb(51, 51, 51);font-weight: 700;font-style: normal;">org</span><span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 116px;text-decoration: none solid rgb(51, 51, 51);font-weight: 400;font-style: normal;">.springframework</span><span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 29px;text-decoration: none solid rgb(51, 51, 51);font-weight: 400;font-style: normal;">.web</span><span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 36px;text-decoration: none solid rgb(51, 51, 51);font-weight: 400;font-style: normal;">.bind</span><span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 79px;text-decoration: none solid rgb(51, 51, 51);font-weight: 400;font-style: normal;">.annotation</span><span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 101px;text-decoration: none solid rgb(51, 51, 51);font-weight: 400;font-style: normal;">.RequestMethod</span>;<br mpa-from-tpl="t"><span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 43px;text-decoration: none solid rgb(51, 51, 51);font-weight: 700;font-style: normal;">import</span> <span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 22px;text-decoration: none solid rgb(51, 51, 51);font-weight: 700;font-style: normal;">org</span><span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 116px;text-decoration: none solid rgb(51, 51, 51);font-weight: 400;font-style: normal;">.springframework</span><span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 29px;text-decoration: none solid rgb(51, 51, 51);font-weight: 400;font-style: normal;">.web</span><span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 36px;text-decoration: none solid rgb(51, 51, 51);font-weight: 400;font-style: normal;">.bind</span><span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 79px;text-decoration: none solid rgb(51, 51, 51);font-weight: 400;font-style: normal;">.annotation</span><span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 108px;text-decoration: none solid rgb(51, 51, 51);font-weight: 400;font-style: normal;">.RestController</span>;<br mpa-from-tpl="t"><br mpa-from-tpl="t">@<span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 101px;text-decoration: none solid rgb(51, 51, 51);font-weight: 700;font-style: normal;">RestController</span><br mpa-from-tpl="t">@Slf4j<br mpa-from-tpl="t">public class TestController {<br mpa-from-tpl="t"><br mpa-from-tpl="t"> @<span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 101px;text-decoration: none solid rgb(51, 51, 51);font-weight: 700;font-style: normal;">RequestMapping</span>(<span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 36px;text-decoration: none solid rgb(51, 51, 51);font-weight: 700;font-style: normal;">value</span> = <span style="font-size: 13px;color: rgb(221, 17, 68);background: rgba(0, 0, 0, 0);display: inline;width: 51px;text-decoration: none solid rgb(221, 17, 68);font-weight: 400;font-style: normal;">"/test"</span>,method = RequestMethod.GET)<br mpa-from-tpl="t"> public String test(){<br mpa-from-tpl="t"> <span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 43px;text-decoration: none solid rgb(51, 51, 51);font-weight: 700;font-style: normal;">System</span><span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 29px;text-decoration: none solid rgb(51, 51, 51);font-weight: 400;font-style: normal;">.out</span><span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 58px;text-decoration: none solid rgb(51, 51, 51);font-weight: 400;font-style: normal;">.println</span>("这是控制台日志!");<br mpa-from-tpl="t"> <span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 21px;text-decoration: none solid rgb(51, 51, 51);font-weight: 700;font-style: normal;">log</span><span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 36px;text-decoration: none solid rgb(51, 51, 51);font-weight: 400;font-style: normal;">.info</span>("这是输出到文件的日志");<br mpa-from-tpl="t"> <span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 43px;text-decoration: none solid rgb(51, 51, 51);font-weight: 700;font-style: normal;">return</span> "<span style="font-size: 13px;color: rgb(51, 51, 51);background: rgba(0, 0, 0, 0);display: inline;width: 65px;text-decoration: none solid rgb(51, 51, 51);font-weight: 700;font-style: normal;">HELLO-BUG</span>!!!!!!!!!!";<br mpa-from-tpl="t"> }<br mpa-from-tpl="t">}</span><span style=""></span></code></pre> </section> <section style="font-size: 16px;color: rgb(51, 51, 51);font-weight: 400;margin: 20px 8px;line-height: 2em;"> <span style="font-size: 15px;font-family: Optima-Regular, PingFangTC-light;">在resources目录下创建log4j2.xml文件主要看这两个参数�