作者:微信小助手
<section style="margin-bottom: unset;"> <section class="mp_profile_iframe_wrp"> <mp-common-profile class="custom_select_card mp_profile_iframe" data-pluginname="mpprofile" data-weuitheme="light" data-id="MzkxNzM3NTIyMA==" data-headimg="http://mmbiz.qpic.cn/mmbiz_png/EkyTfBwBEovRWNOruewcGnezZO6iaLqFBNc5crQjHHfl343Y1K0J0rZdTR4ViaAGoe4pHo4BIakUCc8sGsU97E8w/0?wx_fmt=png" data-nickname="产品海豚湾" data-alias="pm-dophin-bay" data-signature="人人都是产品经理主编推荐作者,主导过多个产品从0-1,从1-N 的设计。目前从事 SaaS 产品设计和团队管理。B 站搜索:产品海豚湾也可以看相关视频哦。" data-from="0" data-weui-theme="light"></mp-common-profile> <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;letter-spacing: 0.034em;"></span> </section> <section data-support="96编辑器" data-style-id="37374"> <section data-support="96编辑器" data-style-id="37374" style="font-size: 16px;"> <section style="text-align: center;margin-top: 10px;margin-bottom: 10px;"> <section style="display:inline-block;"> <section style="display: flex;align-items:center;"> <section style="width:2.3em;"> <img class="rich_pages wxw-img" data-ratio="0.6119402985074627" data-w="67" data-width="100%" style="display: block;width: 100%;height: auto !important;" src="/upload/89a0fcf45b2b413aca291cc7927172bd.png"> </section> <section style="background-image: linear-gradient(90deg, rgb(244, 250, 254), rgb(60, 172, 244));padding-bottom: 1px;"> <section style="background-color:#fefefe;"> <section style="color: rgb(31, 161, 248);letter-spacing: 2px;padding: 3px 10px;"> <p>前言</p> </section> </section> </section> </section> </section> </section> </section> <p><span style="font-family: PingFangSC-Light;font-size: 15px;letter-spacing: 0.034em;">关于电子合同、电子签章、电子签名,相信不少人听说过甚至体验过。我个人近两年就亲自体验过几次电子签章。第一次是入职某企业时签订劳动合同。当时,在HR的指引下,通过手机端的短信链接直接完成了合同的查看,人脸视频动态口令认证,和合同签署,相比以前需要入职后一段时间才拿到劳动合同,这种效率让我感觉这家企业的HR数字化做得挺好。</span><br></p> <p style="min-height: 24px;"><br></p> <p style="min-height: 24px;"><span style="font-size: 15px;font-family: PingFangSC-Light;">第二次是在贝壳进行二手房交易,当时由于疫情原因,双方无法到场签约,然后贝壳就给我们申请了线上交易,由房管局直接生成合同,通知交易双方完成了房产交易合同的签订,省去了双方跑腿的环节。</span></p> <p style="min-height: 24px;"><br></p> <p style="min-height: 24px;"><span style="font-size: 15px;font-family: PingFangSC-Light;">最近第一次是参与了某个央企的招投标,其中标书制作需要电子加签,也第一次见识到了如何使用UKey直接在PDF文件上加盖电子公章。</span></p> <p style="min-height: 24px;"><br></p> <p style="min-height: 24px;"><span style="font-size: 15px;font-family: PingFangSC-Light;">电子签章工具在很大程度上提高了各类文书、合同的签章效率,并且相比邮寄纸质材料盖章来说,也降低了成本。本篇我们来拆解国内电子合同的头部企业 —— <strong>e签宝</strong>。</span><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;letter-spacing: 0.034em;"></span></p> <section data-support="96编辑器" data-style-id="37374" style="font-size: 16px;"> <section style="text-align: center;margin-top: 10px;margin-bottom: 10px;"> <section style="display:inline-block;"> <section style="display: flex;align-items:center;"> <section style="width:2.3em;"> <img data-ratio="0.6119402985074627" data-w="67" data-width="100%" style="display: block;width: 100%;height: auto !important;" src="/upload/89a0fcf45b2b413aca291cc7927172bd.png"> </section> <section style="background-image: linear-gradient(90deg, rgb(244, 250, 254), rgb(60, 172, 244));padding-bottom: 1px;"> <section style="background-color:#fefefe;"> <section style="color: rgb(31, 161, 248);letter-spacing: 2px;padding: 3px 10px;"> <p>行业分析</p> </section> </section> </section> </section> </section> </section> </section> <p><span style="font-family: PingFangSC-Light;font-size: 15px;letter-spacing: 0.034em;">根据 CB Insights 数据,从 2017 年 1 月到 2022 年 9 月,全球电子签名创业公司融资数量在 2019 年最多,而</span><strong style="font-family: PingFangSC-Light;font-size: 15px;letter-spacing: 0.034em;">融资总规模在 2021 年达到近年的峰值,将近 7 亿美元</strong><span style="font-family: PingFangSC-Light;font-size: 15px;letter-spacing: 0.034em;">。</span><span style="font-family: PingFangSC-Light;font-size: 15px;letter-spacing: 0.034em;"></span></p> <p style="min-height: 24px;"><img class="rich_pages wxw-img" data-ratio="0.5359828141783028" data-type="png" data-w="931" width="931" style="height: auto !important;" src="/upload/8de7fb365bb660bab265f72235b99895.png"></p> <p style="min-height: 24px;"><span style="font-size: 15px;font-family: PingFangSC-Light;">在电子签章领域,企业发展的马太效应明显。美国的 DocuSign 已于 2018 年 4 月 IPO 上市,目前全球市场份额大约在 70% 左右。我国电子签名市场以本土品牌为主,据艾媒咨询《2021中国电子签名行业研究报告》数据,e 签宝、CFCA、数字认证、契约锁及法大大的市场占有率近 40%。其中,我们要讲的e签宝在 2021 年 9 月获得 E 轮 12 亿元融资,累计融资近30亿元,融资总规模仅次于 DocuSign。</span></p> <p style="min-height: 24px;"><img class="rich_pages wxw-img" data-ratio="0.5735129068462402" data-type="png" data-w="891" width="891" style="height: auto !important;" src="/upload/3501efae1a47f346a4f03335d4fba03c.png"></p> <p style="min-height: 24px;"><span style="font-family: PingFangSC-Light;font-size: 15px;">从全球范围看,目前全球已超过 70 个国家承认电子签名的合法性。相关的法律条文也已经比较成熟,例如,我国早在2004年就发布了《<span style="color: rgb(47, 142, 244);">中华人民共和国电子签名法</span>》,并于2005年4月正式实施。</span></p> <p style="min-height: 24px;"><br></p> <p style="min-height: 24px;"><span style="font-family: PingFangSC-Light;font-size: 15px;">行业发展方面,近五年是我国电子签名市场飞速发展时期。从2016年的8.5亿元增长至2020年的108.2亿元,中国电子签名行业<strong>年均复合增长率达到66.33%</strong>。2020年的新冠疫情发生后,进一步推动了电子签名行业发展,行业将维持稳定增长。2022年中国电子签名行业市场规模为217.1亿元,较往年上涨42.1%。未来三年仍将保持30%以上的年复合增长率。预计在2024年,中国电子签名市场规模将超过400亿元。</span></p> <p style="min-height: 24px;"><img class="rich_pages wxw-img" data-ratio="0.6450867052023121" data-type="png" data-w="865" width="786.3636193196639" style="height: auto !important;" src="/upload/6839bb5527cb622d10b3287512bf9aec.png"></p> <p style="min-height: 24px;"><span style="font-size: 15px;font-family: PingFangSC-Light;">政策支持方面。为了促进电子签名行业发展,我国颁布了多项关于支持、鼓励、规范电子签名行业的相关政策,如2022年国务院办公厅发布的《关于加快推进电子证照扩大应用领域和全国互通互认的意见》加快建设形成事业单位、社会组织、个人等各类主体电子签名、电子印章的服务机制和体系,鼓励第三方电子认证服务机构加快创新,实现不同形式的电子证照与电子签名、电子印章融合发展。</span></p> <p style="min-height: 24px;"><br></p> <p style="min-height: 24px;"><span style="font-size: 15px;font-family: PingFangSC-Light;">行业生态上,包括了上游的技术服务商、资质认证(CA机构),中游的电子签厂商、下游服务的政府、企业和个人。同时,整个电子签行业受国家相关机构监管,并且会与第三方保全机构进行合作和寻求司法支持。</span></p> <p style="min-height: 24px;"><img class="rich_pages wxw-img" data-ratio="0.6750599520383693" data-type="png" data-w="834" width="758.1818017486702" style="height: auto !important;" src="/upload/30945b16a622acbe267acb95d6b0857d.png"><br></p> <p><br></p> <section data-support="96编辑器" data-style-id="37374" style="font-size: 16px;"> <section style="text-align: center;margin-top: 10px;margin-bottom: 10px;"> <section style="display:inline-block;"> <section style="display: flex;align-items:center;"> <section style="width:2.3em;"> <img data-ratio="0.6119402985074627" data-w="67" data-width="100%" style="display: block;width: 100%;height: auto !important;" src="/upload/89a0fcf45b2b413aca291cc7927172bd.png"> </section> <section style="background-image: linear-gradient(90deg, rgb(244, 250, 254), rgb(60, 172, 244));padding-bottom: 1px;"> <section style="background-color:#fefefe;"> <section style="color: rgb(31, 161, 248);letter-spacing: 2px;padding: 3px 10px;"> <p>市场分析</p> </section> </section> </section> </section> </section> </section> </section> <p><span style="font-family: PingFangSC-Light;font-size: 15px;letter-spacing: 0.034em;">电子签名巨大的业务增长空间,使得这个赛道的玩家数量快速增长,行业内的竞品也日益增多,下面是近几年行业企业数量,可以看到不断有新玩家进入电子签这个领域。</span><span style="font-family: PingFangSC-Light;font-size: 15px;letter-spacing: 0.034em;"></span></p> <p style="min-height: 24px;"><img class="rich_pages wxw-img" data-ratio="0.620958751393534" data-type="png" data-w="897" width="815.4545277800446" style="height: auto !important;" src="/upload/42f7d373102df9457f79d8c870aa833a.png"></p> <p style="min-height: 24px;"><span style="font-size: 15px;font-family: PingFangSC-Light;">就目前来看,行业内的玩家主要有三类:</span></p> <ul class="list-paddingleft-1" style="padding-left: 30px;"> <li><p><span style="font-size: 15px;font-family: PingFangSC-Light;">以e签宝、法大大、上上签等为代表的头部初创SaaS电子签厂商;</span></p></li> <li><p><span style="font-size: 15px;font-family: PingFangSC-Light;">以腾讯、字节、阿里、京东等为代表的互联网电子签厂商;</span></p></li> <li><p><span style="font-size: 15px;font-family: PingFangSC-Light;">以传统软件厂商转型而来的电子签厂商,如泛微推出的契约锁等。</span><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;letter-spacing: 0.034em;"></span></p></li> </ul> <section data-style-id="32715"> <section data-align="title" style="margin-top: 10px;margin-bottom: 10px;margin-left: 10px;"> <section style="text-align: left;"> <section style="display:inline-block;"> <section style="display: flex;justify-content: center;align-items: center;"> <section style="margin-right: 3px;width: 4px;height:18px;background-color: #f36502;transform: skew(-25deg);-webkit-transform: skew(-25deg);-moz-transform: skew(-25deg);-ms-transform: skew(-25deg);-o-transform: skew(-25deg);"> <br> </section> <section style="margin-right: 3px;width: 4px;height:18px;background-color: #f36502;transform: skew(-25deg);-webkit-transform: skew(-25deg);-moz-transform: skew(-25deg);-ms-transform: skew(-25deg);-o-transform: skew(-25deg);"> <br> </section> <section style="width: 4px;height: 18px;background-color: #f36502;transform: skew(-25deg);-webkit-transform: skew(-25deg);-moz-transform: skew(-25deg);-ms-transform: skew(-25deg);-o-transform: skew(-25deg);"> <br> </section> <section style="margin-left:6px;letter-spacing:2px;color:#f36502;font-size:16px;"> <p><em><strong>SaaS 厂商</strong></em></p> </section> </section> </section> </section> </section> </section> <p><span style="font-family: PingFangSC-Light;font-size: 15px;letter-spacing: 0.034em;">电子签SaaS厂商实际发展的年限比我想象得要早很多。比如,法大大成立于2014年,也已经有近10年的发展历史。而本篇要介绍的e签宝更是在2002年就已经成立,有着超过20年的行业经验。可以看到,电子签这个领域本身还是具备一定的准入门槛,需要具备相应的安全资质和牌照,先发优势还是十分重要。</span><br></p> <p style="min-height: 24px;"><br></p> <p style="min-height: 24px;"><span style="font-size: 15px;font-family: PingFangSC-Light;">作为较早入局的SaaS电子签厂商,他们在技术、产品、服务等方面具有先发优势,专业度更高。但是,单纯的电子签功能还是相对单薄,很难成为企业数字化转型的核心推动力量。此外,这类厂商积累的B端客户不多,获客成本较高,这也是为什么需要接受巨头融资、积极融入大厂生态的原因。</span><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;letter-spacing: 0.034em;"></span></p> <section data-style-id="32715"> <section data-align="title" style="margin-top: 10px;margin-bottom: 10px;margin-left: 10px;"> <section> <section style="display:inline-block;"> <section style="display: flex;justify-content: center;align-items: center;"> <section style="margin-right: 3px;width: 4px;height:18px;background-color: #f36502;transform: skew(-25deg);-webkit-transform: skew(-25deg);-moz-transform: skew(-25deg);-ms-transform: skew(-25deg);-o-transform: skew(-25deg);"> <br> </section> <section style="margin-right: 3px;width: 4px;height:18px;background-color: #f36502;transform: skew(-25deg);-webkit-transform: skew(-25deg);-moz-transform: skew(-25deg);-ms-transform: skew(-25deg);-o-transform: skew(-25deg);"> <br> </section> <section style="width: 4px;height: 18px;background-color:
作者:微信小助手
<h3 data-tool="mdnice编辑器" style="margin: 30px 0px 15px;outline: 0px;font-weight: bold;font-size: 20px;max-width: 100%;font-family: system-ui, -apple-system, "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);color: black;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;"><strong style="outline: 0px;max-width: 100%;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !importan
作者:微信小助手
<section data-tool="mdnice编辑器" data-website="https://www.mdnice.com" style="line-height: 1.6;word-break: break-word;text-align: left;padding: 5px;font-size: 16px;color: rgb(53, 53, 53);word-spacing: 0.8px;letter-spacing: 0.8px;border-radius: 16px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;" data-mpa-powered-by="yiban.io"> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;"><code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(255, 93, 108);">@RefeshScope</code>这个注解想必大家都用过,在微服务配置中心的场景下经常出现,他可以用来刷新Bean中的属性配置,那大家对他的实现原理了解吗?它为什么可以做到动态刷新呢?</p> <h2 data-tool="mdnice编辑器" style="font-weight: bold;color: black;font-size: 22px;margin-top: 20px;margin-right: 10px;"><span style="display: none;"></span><span style="font-size: 18px;color: rgb(234, 84, 41);letter-spacing: 0.5444px;padding-bottom: 10px;border-bottom: 2px solid rgb(234, 84, 41);visibility: visible;"><span style="color: rgb(248, 57, 41);">注解的作用</span></span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;"><code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(255, 93, 108);">@RefreshScope</code>注解是Spring Cloud中的一个注解,用来实现Bean中属性的动态刷新。</p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><span style="display: block;background: url("https://mmbiz.qpic.cn/mmbiz_svg/A7sq8BD8oezBibiciavS1eDQYFIBQOMf4SlpOl8GRYtbJFtuUwicHjwK4cnJRr0zKenayQU8deKaBmKicr8EL05XOPYJruL5NSsLu/640?wx_fmt=svg") 10px 10px / 40px no-repeat rgb(255, 255, 255);height: 30px;width: 100%;margin-bottom: -7px;border-radius: 5px;"></span><code style="overflow-x: auto;padding: 16px;color: black;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;font-size: 12px;-webkit-overflow-scrolling: touch;padding-top: 15px;background: #fff;border-radius: 5px;"><span style="color: #007400;line-height: 26px;">/**<br> * Convenience annotation to put a <code><span style="font-weight: bold;line-height: 26px;">@Bean</span></code> definition in<br> * {<span style="font-weight: bold;line-height: 26px;">@link</span> org.springframework.cloud.context.scope.refresh.RefreshScope refresh scope}.<br> * Beans annotated this way can be refreshed at runtime and any components that are using<br> * them will get a new instance on the next method call, fully initialized and injected<br> * with all dependencies.<br> *<br> * <span style="font-weight: bold;line-height: 26px;">@author</span> Dave Syer<br> *<br> */</span><br><span style="color: #643820;line-height: 26px;">@Target</span>({ ElementType.TYPE, ElementType.METHOD })<br><span style="color: #643820;line-height: 26px;">@Retention</span>(RetentionPolicy.RUNTIME)<br><span style="color: #643820;line-height: 26px;">@Scope</span>(<span style="color: #c41a16;line-height: 26px;">"refresh"</span>)<br><span style="color: #643820;line-height: 26px;">@Documented</span><br><span style="color: #aa0d91;line-height: 26px;">public</span> <span style="color: #643820;line-height: 26px;">@interface</span> RefreshScope {<br><br> <span style="color: #007400;line-height: 26px;">/**<br> * <span style="font-weight: bold;line-height: 26px;">@see</span> Scope#proxyMode()<br> * <span style="font-weight: bold;line-height: 26px;">@return</span> proxy mode<br> */</span><br> <span style="line-height: 26px;">ScopedProxyMode <span style="color: #1c00cf;line-height: 26px;">proxyMode</span><span style="color: #5c2699;line-height: 26px;">()</span> <span style="color: #aa0d91;line-height: 26px;">default</span> ScopedProxyMode.TARGET_CLASS</span>;<br><br>}<br></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">上面是<code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(255, 93, 108);">RefreshScope</code>的源码,该注解被<code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(255, 93, 108);">@Scope</code>注解使用,<code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(255, 93, 108);">@Scope</code>用来比较<code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(255, 93, 108);">Spring Bean</code>的作用域,具体使用参考相关文章。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">注解的属性<code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(255, 93, 108);">proxyMode</code>默认使用<code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(255, 93, 108);">TARGET_CLASS</code>作为代理。</p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;color: black;font-size: 20px;"><span style="display: none;"></span><span style="font-size: 16px;color: #222;">实例</span><span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">1、controller中添加<code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(255, 93, 108);">@RefreshScope</code></p> <p><img class="rich_pages wxw-img" data-ratio="0.5860023724792408" data-type="png" data-w="843" style="height: auto !important;" src="/upload/def6f6d0305eebc3b13c62a5f4dcf728.png"></p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">2、nacos配置中心中配置</p> <p><img class="rich_pages wxw-img" data-ratio="0.5990510083036773" data-type="png" data-w="843" style="height: auto !important;" src="/upload/a95cf654b795235b46997efd3f84ed52.png"></p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">3、验证, 修改配置中心后,可以不重启动,刷新配置</p> <p><img class="rich_pages wxw-img" data-ratio="0.2313167259786477" data-type="png" data-w="843" style="height: auto !important;" src="/upload/725a69a54ee74fdb8fe6f105b7a83f6b.png"></p> <p><img class="rich_pages wxw-img" data-ratio="0.6429418742586003" data-type="png" data-w="843" style="height: auto !important;" src="/upload/81161396314b58cdb9be63b0299de012.png"></p> <p><img class="rich_pages wxw-img" data-ratio="0.22182680901542112" data-type="png" data-w="843" style="height: auto !important;" src="/upload/3b2485330ad31029eaf5e860b4f97223.png"></p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">4、去掉<code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(255, 93, 108);">@RefreshScope</code> 就不会自动刷新。</p> <h2 data-tool="mdnice编辑器" style="font-weight: bold;color: black;font-size: 22px;margin-top: 20px;margin-right: 10px;"><span style="display: none;"></span><span style="font-size: 18px;color: rgb(234, 84, 41);letter-spacing: 0.5444px;padding-bottom: 10px;border-bottom: 2px solid rgb(234, 84, 41);visibility: visible;"><span style="color: rgb(248, 57, 41);">原理解析</span></span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">为了实现动态刷新配置,主要就是想办法达成以下两个核心目标:</p> <ol data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;color: rgb(248, 57, 41);" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(53, 53, 53);"> 让Spring容器重新加载Environment环境配置变量 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(53, 53, 53);"> Spring Bean重新创建生成 </section></li> </ol> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;"><code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(255, 93, 108);">@RefreshScope</code>主要就是基于<code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(255, 93, 108);">@Scope</code>注解的作用域代理的基础上进行扩展实现的,加了<code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(255, 93, 108);">@RefreshScope</code>注解的类,在被Bean工厂创建后会加入自己的<code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(255, 93, 108);">refresh scope</code> 这个<code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(255, 93, 108);">Bean</code>缓存中,后续会优先从Bean缓存中获取,当配置中心发生了变更,会把变更的配置更新到spring容器的<code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(255, 93, 108);">Environment</code>中,并且同事bean缓存就会被清空,从而就会从bean工厂中创建bean实例了,而这次创建bean实例的时候就会继续经历这个bean的生命周期,使得<code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(255, 93, 108);">@Value</code>属性值能够从<code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(255, 93, 108);">Environment</code>中获取到最新的属性值,这样整个过程就达到了动态刷新配置的效果。关注公众号:码猿技术专栏,回复关键词:1111 获取阿里内部Java性能调优手册~</p> <p><img class="rich_pages wxw-img" data-ratio="0.9786476868327402" data-type="png" data-w="843" style="height: auto !important;" src="/upload/9da09c137cb0c773d034cd3aa459bcc2.png"></p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;color: black;font-size: 20px;"><span style="display: none;"></span><span style="font-size: 16px;color: #222;">获取RefreshScope注解的Bean</span><span style="display: none;"></span></h3> <p><img class="rich_pages wxw-img" data-ratio="0.5088967971530249" data-type="png" data-w="843" style="height: auto !important;" src="/upload/cdd040e0fed2379b39e7b4fc081c5640.png"></p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">通过打上断点查看堆栈可知:</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">1、因为Class被加上了<code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(255, 93, 108);">@RefreshScope</code>注解,那么这个BeanDefinition信息中的scope为refresh,在getBean的的时候会单独处理逻辑。</p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><span style="display: block;background: url("https://mmbiz.qpic.cn/mmbiz_svg/A7sq8BD8oezBibiciavS1eDQYFIBQOMf4SlpOl8GRYtbJFtuUwicHjwK4cnJRr0zKenayQU8deKaBmKicr8EL05XOPYJruL5NSsLu/640?wx_fmt=svg") 10px 10px / 40px no-repeat rgb(255, 255, 255);height: 30px;width: 100%;margin-bottom: -7px;border-radius: 5px;"></span><code style="overflow-x: auto;padding: 16px;color: black;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;font-size: 12px;-webkit-overflow-scrolling: touch;padding-top: 15px;background: #fff;border-radius: 5px;"><span style="color: #aa0d91;line-height: 26px;">public</span> <span style="color: #aa0d91;line-height: 26px;">abstract</span> <span style="line-height: 26px;"><span style="color: #aa0d91;line-height: 26px;">class</span> <span style="color: #5c2699;line-height: 26px;">AbstractBeanFactory</span> <span style="color: #aa0d91;line-height: 26px;">extends</span> <span style="color: #5c2699;line-height: 26px;">FactoryBeanRegistrySupport</span> <span style="color: #aa0d91;line-height: 26px;">implements</span> <span style="color: #5c2699;line-height: 26px;">ConfigurableBeanFactory</span> </span>{<br><br><span style="color: #aa0d91;line-height: 26px;">protected</span> <T> <span style="line-height: 26px;">T <span style="color: #1c00cf;line-height: 26px;">doGetBean</span><span style="color: #5c2699;line-height: 26px;">(<br> String name, @Nullable Class<T> requiredType, @Nullable Object[] args, <span style="color: #aa0d91;line-height: 26px;">boolean</span> typeCheckOnly)</span><br> <span style="color: #aa0d91;line-height: 26px;">throws</span> BeansException </span>{<br><br> <span style="color: #007400;line-height: 26px;">// 如果scope是单例的情况, 这里不进行分析</span><br> <span style="color: #aa0d91;line-height: 26px;">if</span> (mbd.isSingleton()) {<br> .....<br> }<br> <span style="color: #007400;line-height: 26px;">// 如果scope是prototype的情况, 这里不进行分析</span><br> <span style="color: #aa0d91;line-height: 26px;">else</span> <span style="color: #aa0d91;line-height: 26px;">if</span> (mbd.isPrototype()) {<br> ......<br> }<br> <span style="color: #007400;line-height: 26px;">// 如果scope是其他的情况,本例中是reresh</span><br> <span style="color: #aa0d91;line-height: 26px;">else</span> {<br> String scopeName = mbd.getScope();<br> <span style="color: #aa0d91;line-height: 26px;">if</span> (!StringUtils.hasLength(scopeName)) {<br> <span style="color: #aa0d91;line-height: 26px;">throw</span> <span style="color: #aa0d91;line-height: 26px;">new</span> IllegalStateException(<span style="color: #c41a16;line-height: 26px;">"No scope name defined for bean '"</span> + beanName + <span style="color: #c41a16;line-height: 26px;">"'"</span>);<br> }<br> <span style="color: #007400;line-height: 26px;">// 获取refresh scope的实现类RefreshScope,这个类在哪里注入,我们后面讲</span><br> Scope scope = <span style="color: #aa0d91;line-height: 26px;">this</span>.scopes.get(scopeName);<br> <span style="color: #aa0d91;line-height: 26px;">if</span> (scope == <span style="color: #aa0d91;line-height: 26px;">null</span>) {<br> <span style="color: #aa0d91;line-height: 26px;">throw</span> <span style="color: #aa0d91;line-height: 26px;">new</span> IllegalStateException(<span style="color: #c41a16;line-height: 26px;">"No Scope registered for scope name '"</span> + scopeName + <span style="color: #c41a16;line-height: 26px;">"'"</span>);<br> }<br> <span style="color: #aa0d91;line-height: 26px;">try</span> {<br> <span style="color: #007400;line-height: 26px;">// 这边是获取bean,调用的是RefreshScope中的的方法</span><br> Object scopedInstance = scope.get(beanName, () -> {<br> beforePrototypeCreation(beanName);<br> <span style="color: #aa0d91;line-height: 26px;">try</span> {<br> <span style="color: #aa0d91;line-height: 26px;">return</span> createBean(beanName, mbd, args);<br> }<br> <span style="color: #aa0d91;line-height: 26px;">finally</span> {<br> afterPrototypeCreation(beanName);<br> }<br> });<br> beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);<br> }<br> <span style="color: #aa0d91;line-height: 26px;">catch</span> (IllegalStateException ex) {<br> <span style="color: #aa0d91;line-height: 26px;">throw</span> <span style="color: #aa0d91;line-height: 26px;">new</span> ScopeNotActiveException(beanName, scopeName, ex);<br> }<br> }<br> }<br> <span style="color: #aa0d91;line-height: 26px;">catch</span> (BeansException ex) {<br> beanCreation.tag(<span style="color: #c41a16;line-height: 26px;">"exception"</span>, ex.getClass().toString());<br> beanCreation.tag(<span style="color: #c41a16;line-height: 26px;">"message"</span>, String.valueOf(ex.getMessage()));<br> cleanupAfterBeanCreationFailure(beanName);<br> <span style="color: #aa0d91;line-height: 26px;">throw</span> ex;<br> }<br> <span style="color: #aa0d91;line-height: 26px;">finally</span> {<br> beanCreation.end();<br> }<br> }<br><br> <span style="color: #aa0d91;line-height: 26px;">return</span> adaptBeanInstance(name, beanInstance, requiredType);<br> }<br> <br>}<br></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">2、<code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(255, 93, 108);">RefreshScope</code>继承成了<code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(255, 93, 108);">GenericScope</code>类,最终调用的的是<code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(255, 93, 108);">GenericScope</code>的<code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(255, 93, 108);">get</code>方法</p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><span style="display: block;background: url("https://mmbiz.qpic.cn/mmbiz_svg/A7sq8BD8oezBibiciavS1eDQYFIBQOMf4SlpOl8GRYtbJFtuUwicHjwK4cnJRr0zKenayQU8deKaBmKicr8EL05XOPYJruL5NSsLu/640?wx_fmt=svg") 10px 10px / 40px no-repeat rgb(255, 255, 255);height: 30px;width: 100%;margin-bottom: -7px;border-radius: 5px;"></span><code style="overflow-x: auto;padding: 16px;color: black;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;font-size: 12px;-webkit-overflow-scrolling: touch;padding-top: 15px;background: #fff;border-radius: 5px;"><span style="color: #aa0d91;line-height: 26px;">public</span> <span style="line-height: 26px;"><span style="color: #aa0d91;line-height: 26px;">class</span> <span style="color: #5c2699;line-height: 26px;">GenericScope</span><br> <span style="color: #aa0d91;line-height: 26px;">implements</span> <span style="color: #5c2699;line-height: 26px;">Scope</span>, <span style="color: #5c2699;line-height: 26px;">BeanFactoryPostProcessor</span>, <span style="color: #5c2699;line-height: 26px;">BeanDefinitionRegistryPostProcessor</span>, <span style="color: #5c2699;line-height: 26px;">DisposableBean</span> </span>{<br> <span style="color: #643820;line-height: 26px;">@Override</span><br> <br> <span style="line-height: 26px;"><span style="color: #aa0d91;line-height: 26px;">public</span> Object <span style="color: #1c00cf;line-height: 26px;">get</span><span style="color: #5c2699;line-height: 26px;">(String name, ObjectFactory<?> objectFactory)</span> </span>{<br> <span style="color: #007400;line-height: 26px;">// 将bean添加到缓存cache中</span><br> BeanLifecycleWrapper value = <span style="color: #aa0d91;line-height: 26px;">this</span>.cache.put(name, <span style="color: #aa0d91;line-height: 26px;">new</span> BeanLifecycleWrapper(name, objectFactory));<br> <span style="color: #aa0d91;line-height: 26px;">this</span>.locks.putIfAbsent(name, <span style="color: #aa0d91;line-height: 26px;">new</span> ReentrantReadWriteLock());<br> <span style="color: #aa0d91;line-height: 26px;">try</span> {<br> <span style="color: #007400;line-height: 26px;">// 调用下面的getBean方法</span><br> <span style="color: #aa0d91;line-height: 26px;">return</span> value.getBean();<br> }<br> <span style="color: #aa0d91;line-height: 26px;">catch</span> (RuntimeException e) {<br> <span style="color: #aa0d91;line-height: 26px;">this</span>.errors.put(name, e);<br> <span style="color: #aa0d91;line-height: 26px;">throw</span> e;<br> }<br> } <br><br><span style="color: #aa0d91;line-height: 26px;">private</span> <span style="color: #aa0d91;line-height: 26px;">static</span> <span style="line-height: 26px;"><span style="color: #aa0d91;line-height: 26px;">class</span> <span style="color: #5c2699;line-height: 26px;">BeanLifecycleWrapper</span> </span>{<br> <br> <span style="line-height: 26px;"><span style="color: #aa0d91;line-height: 26px;">public</span> Object <span style="color: #1c00cf;line-height: 26px;">getBean</span><span style="color: #5c2699;line-height: 26px;">()</span> </span>{<br> <span style="color: #007400;line-height: 26px;">// 如果bean为空,则创建bean</span><br> <span style="color: #aa0d91;line-height: 26px;">if</span> (<span style="color: #aa0d91;line-height: 26px;">this</span>.bean == <span style="color: #aa0d91;line-height: 26px;">null</span>) {<br> <span style="color: #aa0d91;line-height: 26px;">synchronized</span> (<span style="color: #aa0d91;line-height: 26px;">this</span>.name) {<br> <span style="color: #aa0d91;line-height: 26px;">if</span> (<span style="color: #aa0d91;line-height: 26px;">this</span>.bean == <span style="color: #aa0d91;line-height: 26px;">null</span>) {<br> <span style="color: #aa0d91;line-height: 26px;">this</span>.bean = <span style="color: #aa0d91;line-height: 26px;">this</span>.objectFactory.getObject();<br> }<br> }<br> }<br> <span style="color: #007400;line-height: 26px;">// 否则返回之前创建好的bean</span><br> <span style="color: #aa0d91;line-height: 26px;">return</span> <span style="color: #aa0d91;line-height: 26px;">this</span>.bean;<br> }<br> }<br> }<br></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;"><span style="font-weight: 700;color: rgb(248, 57, 41);">小结:</span></p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">从这边的代码中可以印证了上面的说法,创建后的Bean会缓存到scope的cache中,优先从缓存中获取,如果缓存中是null, 则重新走一遍create bean的流程。</p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;color: black;font-size: 20px;"><span style="display: none;"></span><span style="font-size: 16px;color: #222;">RefeshScope Bean的创建</span><span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">上面的在getBean的时候依赖到RefreshScope这个Bean,那么这个Bean是在什么时候加入到Spring Bean中的呢?答案就是<code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(255, 93, 108);">RefreshAutoConfiguration</code>。</p> <p><img class="rich_pages wxw-img" data-ratio="0.5527876631079478" data-type="png" data-w="843" style="height: auto !important;" src="/upload/e21005ad511841b847417c92b68c586d.png"></p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;color: black;font-size: 20px;"><span style="display: none;"></span><span style="font-size: 16px;color: #222;">配置中心刷新后刷新Bean缓存</span><span style="display: none;"></span></h3> <p><img class="rich_pages wxw-img" data-ratio="0.6856465005931198" data-type="png" data-w="843" style="height: auto !important;" src="/upload/c5bd51583a892a6c38ebb8534bfc4147.png"></p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">1、配置中心发生变化后,会收到一个<code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(255, 93, 108);">RefreshEvent</code>事件,<code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(255, 93, 108);">RefreshEventListner</code>监听器会监听到这个事件。</p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><span style="display: block;background: url("https://mmbiz.qpic.cn/mmbiz_svg/A7sq8BD8oezBibiciavS1eDQYFIBQOMf4SlpOl8GRYtbJFtuUwicHjwK4cnJRr0zKenayQU8deKaBmKicr8EL05XOPYJruL5NSsLu/640?wx_fmt=svg") 10px 10px / 40px no-repeat rgb(255, 255, 255);height: 30px;width: 100%;margin-bottom: -7px;border-radius: 5px;"></span><code style="overflow-x: auto;padding: 16px;color: black;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;font-size: 12px;-webkit-overflow-scrolling: touch;padding-top: 15px;background: #fff;border-radius: 5px;"><span style="color: #aa0d91;line-height: 26px;">public</span> <span style="line-height: 26px;"><span style="color: #aa0d91;line-height: 26px;">class</span> <span style="color: #5c2699;line-height: 26px;">RefreshEventListener</span> <span style="color: #aa0d91;line-height: 26px;">implements</span> <span style="color: #5c2699;line-height: 26px;">SmartApplicationListener</span> </span>{<br><br> <br>........<br><br> <span style="line-height: 26px;"><span style="color: #aa0d91;line-height: 26px;">public</span> <span style="color: #aa0d91;line-height: 26px;">void</span> <span style="color: #1c00cf;line-height: 26px;">handle</span><span style="color: #5c2699;line-height: 26px;">(RefreshEvent event)</span> </span>{<br> <span style="color: #aa0d91;line-height: 26px;">if</span> (<span style="color: #aa0d91;line-height: 26px;">this</span>.ready.get()) { <span style="color: #007400;line-height: 26px;">// don't handle events before app is ready</span><br> log.debug(<span style="color: #c41a16;line-height: 26px;">"Event received "</span> + event.getEventDesc());<br> <span style="color: #007400;line-height: 26px;">// 会调用refresh方法,进行刷新</span><br> Set<String> keys = <span style="color: #aa0d91;line-height: 26px;">this</span>.refresh.refresh();<br> log.info(<span style="color: #c41a16;line-height: 26px;">"Refresh keys changed: "</span> + keys);<br> }<br> }<br><br>}<br><br><span style="color: #007400;line-height: 26px;">// 这个是ContextRefresher类中的刷新方法</span><br><span style="line-height: 26px;"><span style="color: #aa0d91;line-height: 26px;">public</span> <span style="color: #aa0d91;line-height: 26px;">synchronized</span> Set<String> <span style="color: #1c00cf;line-height: 26px;">refresh</span><span style="color: #5c2699;line-height: 26px;">()</span> </span>{<br> <span style="color: #007400;line-height: 26px;">// 刷新spring的envirionment 变量配置</span><br> Set<String> keys = refreshEnvironment();<br> <span style="color: #007400;line-height: 26px;">// 刷新其他scope</span><br> <span style="color: #aa0d91;line-height: 26px;">this</span>.scope.refreshAll();<br> <span style="color: #aa0d91;line-height: 26px;">return</span> keys;<br> }<br></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">2、refresh方法最终调用destroy方法,清空之前缓存的bean</p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><span style="display: block;background: url("https://mmbiz.qpic.cn/mmbiz_svg/A7sq8BD8oezBibiciavS1eDQYFIBQOMf4SlpOl8GRYtbJFtuUwicHjwK4cnJRr0zKenayQU8deKaBmKicr8EL05XOPYJruL5NSsLu/640?wx_fmt=svg") 10px 10px / 40px no-repeat rgb(255, 255, 255);height: 30px;width: 100%;margin-bottom: -7px;border-radius: 5px;"></span><code style="overflow-x: auto;padding: 16px;color: black;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;font-size: 12px;-webkit-overflow-scrolling: touch;padding-top: 15px;background: #fff;border-radius: 5px;"><span style="color: #aa0d91;line-height: 26px;">public</span> <span style="line-height: 26px;"><span style="color: #aa0d91;line-height: 26px;">class</span> <span style="color: #5c2699;line-height: 26px;">RefreshScope</span> <span style="color: #aa0d91;line-height: 26px;">extends</span> <span style="color: #5c2699;line-height: 26px;">GenericScope</span><br> <span style="color: #aa0d91;line-height: 26px;">implements</span> <span style="color: #5c2699;line-height: 26px;">ApplicationContextAware</span>, <span style="color: #5c2699;line-height: 26px;">ApplicationListener</span><<span style="color: #5c2699;line-height: 26px;">ContextRefreshedEvent</span>>, <span style="color: #5c2699;line-height: 26px;">Ordered</span> </span>{<br><br> <span style="color: #643820;line-height: 26px;">@ManagedOperation</span>(description = <span style="color: #c41a16;line-height: 26px;">"Dispose of the current instance of all beans "</span><br> + <span style="color: #c41a16;line-height: 26px;">"in this scope and force a refresh on next method execution."</span>)<br> <span style="line-height: 26px;"><span style="color: #aa0d91;line-height: 26px;">public</span> <span style="color: #aa0d91;line-height: 26px;">void</span> <span style="color: #1c00cf;line-height: 26px;">refreshAll</span><span style="color: #5c2699;line-height: 26px;">()</span> </span>{<br> <span style="color: #007400;line-height: 26px;">// 调用父类的destroy</span><br> <span style="color: #aa0d91;line-height: 26px;">super</span>.destroy();<br> <span style="color: #aa0d91;line-height: 26px;">this</span>.context.publishEvent(<span style="color: #aa0d91;line-height: 26px;">new</span> RefreshScopeRefreshedEvent());<br> }<br>}<br><br><br><span style="color: #643820;line-height: 26px;">@Override</span><br> <span style="line-height: 26px;"><span style="color: #aa0d91;line-height: 26px;">public</span> <span style="color: #aa0d91;line-height: 26px;">void</span> <span style="color: #1c00cf;line-height: 26px;">destroy</span><span style="color: #5c2699;line-height: 26px;">()</span> </span>{<br> List<Throwable> errors = <span style="color: #aa0d91;line-height: 26px;">new</span> ArrayList<Throwable>();<br> Collection<BeanLifecycleWrapper> wrappers = <span style="color: #aa0d91;line-height: 26px;">this</span>.cache.clear();<br> <span style="color: #aa0d91;line-height: 26px;">for</span> (BeanLifecycleWrapper wrapper : wrappers) {<br> <span style="color: #aa0d91;line-height: 26px;">try</span> {<br> Lock lock = <span style="color: #aa0d91;line-height: 26px;">this</span>.locks.get(wrapper.getName()).writeLock();<br> lock.lock();<br> <span style="color: #aa0d91;line-height: 26px;">try</span> {<br> <span style="color: #007400;line-height: 26px;">// 这里主要就是把之前的bean设置为null, 就会重新走createBean的流程了</span><br> wrapper.destroy();<br> }<br> <span style="color: #aa0d91;line-height: 26px;">finally</span> {<br> lock.unlock();<br> }<br> }<br> <span style="color: #aa0d91;line-height: 26px;">catch</span> (RuntimeException e) {<br> errors.add(e);<br> }<br> }<br> <span style="color: #aa0d91;line-height: 26px;">if</span> (!errors.isEmpty()) {<br> <span style="color: #aa0d91;line-height: 26px;">throw</span> wrapIfNecessary(errors.get(<span style="color: #1c00cf;line-height: 26px;">0</span>));<br> }<br> <span style="color: #aa0d91;line-height: 26px;">this</span>.errors.clear();<br> }<br></code></pre> <h2 data-tool="mdnice编辑器" style="font-weight: bold;color: black;font-size: 22px;margin-top: 20px;margin-right: 10px;"><span style="display: none;"></span><span style="font-size: 18px;color: rgb(234, 84, 41);letter-spacing: 0.5444px;padding-bottom: 10px;border-bottom: 2px solid rgb(234, 84, 41);visibility: visible;"><span style="color: rgb(248, 57, 41);">总结</span></span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">上面是这个RefreshScope实现动态刷新大致的原理,其中里面还有很多细节,可能需要留给大家自己debug去深入理解。</p> <h2 data-tool="mdnice编辑器" style="font-weight: bold;color: black;font-size: 22px;margin-top: 20px;margin-right: 10px;"><span style="display: none;"></span><span style="font-size: 18px;color: rgb(234, 84, 41);letter-spacing: 0.5444px;padding-bottom: 10px;border-bottom: 2px solid rgb(234, 84, 41);visibility: visible;">最后说一句(别白嫖,求关注)</span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">陈某每一篇文章都是精心输出,如果这篇文章对你有所帮助,或者有所启发的话,帮忙<span style="font-weight: 700;color: rgb(248, 57, 41);">点赞</span>、<span style="font-weight: 700;color: rgb(248, 57, 41);">在看</span>、<span style="font-weight: 700;color: rgb(248, 57, 41);">转发</span>、<span style="font-weight: 700;color: rgb(248, 57, 41);">收藏</span>,你的支持就是我坚持下去的最大动力!</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">另外陈某的<a href="https://mp.weixin.qq.com/s?__biz=MzU3MDAzNDg1MA==&mid=2247524437&idx=1&sn=32699e9afede86fe52136c38f844c620&chksm=fcf7bf98cb80368e5eff366916e6b251fa7ca7526b44202d59032863d89f353545f0c0ebfff2&token=339165402&lang=zh_CN&scene=21#wechat_redirect" style="color: rgb(248, 57, 41);border-bottom: 1px solid rgb(248, 57, 41);" data-linktype="2">知识星球</a>开通了,公众号回复关键词:<span style="font-weight: 700;color: rgb(248, 57, 41);">知识星球</span> 获取限量<span style="font-weight: 700;color: rgb(248, 57, 41);">20元</span>优惠券加入只需<span style="font-weight: 700;color: rgb(248, 57, 41);">109</span>元,星球回馈的价值巨大,目前更新了<span style="font-weight: 700;color: rgb(248, 57, 41);">Spring全家桶实战系列</span>、<span style="font-weight: 700;color: rgb(248, 57, 41);">亿级数据分库分表实战</span>、<span style="font-weight: 700;color: rgb(248, 57, 41);">DDD微服务实战专栏</span>、<span style="font-weight: 700;color: rgb(248, 57, 41);">我要进大厂、Spring,Mybatis等框架源码、架构实战22讲、精尽RocketMQ</span>等....每增加一个专栏价格将上涨20元</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;border-radius: 16px;overflow: hidden;"> <img class="rich_pages wxw-img" data-ratio="1.0398148148148147" data-w="1080" style="border-radius: 6px;display: block;margin: 20px auto;max-width: 95%;object-fit: contain;height: auto !important;" src="/upload/d2a99d6b013cd820afa10b391d4794be.png"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">关注公众号:【码猿技术专栏】,公众号内有超赞的粉丝福利,回复:加群,可以加入技术讨论群,和大家一起讨论技术,吹牛逼!</p> <section class="mp_profile_iframe_wrp"> <mp-common-profile class="custom_select_card mp_profile_iframe" data-pluginname="mpprofile" data-weuitheme="light" data-id="MzU3MDAzNDg1MA==" data-headimg="http://mmbiz.qpic.cn/mmbiz_png/19cc2hfD2rA07Je2pY1o0ic2KcPRn44icO8GVcKRdwiaYvrE6bNeTbWPicyV7c7jWmSyzsiaWASjjckzBcsJMJw06pA/0?wx_fmt=png" data-nickname="码猿技术专栏" data-alias="oneswholife" data-signature="前蚂蚁P8,纯粹的技术人,以专栏的形式分享java全栈技术:SSM、Spring全家桶、微服务、MySQL、分布式、中间件、Linux、偶尔讲点运维Jenkins、Nexus、Docker、ELK.." data-from="0" data-weui-theme="light"></mp-common-profile> </section> </section> <p style="display: none;"> <mp-style-type data-value="3"></mp-style-type></p>
作者:微信小助手
<section class="mp_profile_iframe_wrp" data-mpa-powered-by="yiban.io"> <mp-common-profile class="custom_select_card mp_profile_iframe" data-pluginname="mpprofile" data-weuitheme="light" data-id="MzkyNTI5NTQ1NQ==" data-headimg="http://mmbiz.qpic.cn/mmbiz_png/wxcY9TH8dPsYAnrjaZktBe0iahF8ic9QkF26cAw8pK6HPR1bfFEImdyJspvkQvQwmnYxP4eEVW60ewVVickcWXnrQ/0?wx_fmt=png" data-nickname="架构文摘" data-alias="ArchDigest" data-signature="每天一篇架构领域重磅好文,涉及一线互联网公司应用架构(高可用、高性能、高稳定)、大数据、机器学习、Java架构等各个热门领域。" data-from="0" data-weui-theme="light"></mp-common-profile> </section> <section> <span style="font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Apple Color Emoji", "Emoji Symbols Font", "Segoe UI Symbol", Arial, sans-serif;background-color: rgb(255, 255, 255);color: rgb(34, 34, 34);font-size: 16px;letter-spacing: 0.544px;widows: 1;word-spacing: 1px;caret-color: rgb(34, 34, 34);"><br></span> </section> <section> <span style="font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Apple Color Emoji", "Emoji Symbols Font", "Segoe UI Symbol", Arial, sans-serif;background-color: rgb(255, 255, 255);color: rgb(34, 34, 34);font-size: 16px;letter-spacing: 0.544px;widows: 1;word-spacing: 1px;caret-color: rgb(34, 34, 34);">平常工作中都听说了DDD,也对DDD做定程度的了解,那么怎么将一个新项目从头开始按照DDD的过程进行划分与架构设计呢?</span> </section> <section style="margin-top: 10px;margin-bottom: 10px;outline: 0px;max-width: 100%;font-size: 16px;text-align: left;white-space: normal;widows: 1;word-spacing: 1px;color: rgb(34, 34, 34);letter-spacing: 0.544px;background-color: rgb(255, 255, 255);caret-color: rgb(34, 34, 34);text-size-adjust: inherit;line-height: 1.75em;visibility: visible;font-family: system-ui, -apple-system, 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="outline: 0px;max-width: 100%;font-size: 20px;visibility: visible;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Apple Color Emoji", "Emoji Symbols Font", "Segoe UI Symbol", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"><strong style="outline: 0px;max-width: 100%;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;">一、专业术语</strong></span> </section> <section style="outline: 0px;max-width: 100%;font-size: 16px;text-align: left;white-space: normal;widows: 1;word-spacing: 1px;color: rgb(34, 34, 34);letter-spacing: 0.544px;background-color: rgb(255, 255, 255);caret-color: rgb(34, 34, 34);text-size-adjust: inherit;line-height: 1.75em;visibility: visible;font-family: system-ui, -apple-system, 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="outline: 0px;max-width: 100%;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Apple Color Emoji", "Emoji Symbols Font", "Segoe UI Symbol", Arial, sans-serif;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;"><strong style="outline: 0px;max-width: 100%;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;">各种服务</strong></span> </section> <section style="outline: 0px;max-width: 100%;font-size: 16px;text-align: left;white-space: normal;widows: 1;word-spacing: 1px;color: rgb(34, 34, 34);letter-spacing: 0.544px;background-color: rgb(255, 255, 255);caret-color: rgb(34, 34, 34);text-size-adjust: inherit;line-height: 1.75em;visibility: visible;font-family: system-ui, -apple-system, 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="outline: 0px;max-width: 100%;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Apple Color Emoji", "Emoji Symbols Font", "Segoe UI Symbol", Arial, sans-serif;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;">IAAS:基础设施服务,Infrastructure-as-a-service</span> </section> <section style="outline: 0px;max-width: 100%;font-size: 16px;text-align: left;white-space: normal;widows: 1;word-spacing: 1px;color: rgb(34, 34, 34);letter-spacing: 0.544px;background-color: rgb(255, 255, 255);caret-color: rgb(34, 34, 34);text-size-adjust: inherit;line-height: 1.75em;visibility: visible;font-family: system-ui, -apple-system, 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="outline: 0px;max-width: 100%;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Apple Color Emoji", "Emoji Symbols Font", "Segoe UI Symbol", Arial, sans-serif;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;">PAAS:平台服务,Platform-as-a-service</span> </section> <section style="outline: 0px;max-width: 100%;font-size: 16px;text-align: left;white-space: normal;widows: 1;word-spacing: 1px;color: rgb(34, 34, 34);letter-spacing: 0.544px;background-color: rgb(255, 255, 255);caret-color: rgb(34, 34, 34);text-size-adjust: inherit;line-height: 1.75em;visibility: visible;font-family: system-ui, -apple-system, 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="outline: 0px;max-width: 100%;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Apple Color Emoji", "Emoji Symbols Font", "Segoe UI Symbol", Arial, sans-serif;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;">SAAS:软件服务,Software-as-a-service</span> </section> <section style="outline: 0px;max-width: 100%;font-size: 16px;text-align: left;white-space: normal;widows: 1;word-spacing: 1px;color: rgb(34, 34, 34);letter-spacing: 0.544px;background-color: rgb(255, 255, 255);caret-color: rgb(34, 34, 34);text-size-adjust: inherit;line-height: 1.75em;visibility: visible;font-family: system-ui, -apple-system, 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;"> <br style="outline: 0px;max-width: 100%;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;"> </section> <p style="margin-bottom: 20px;outline: 0px;max-width: 100%;font-size: 16px;white-space: normal;widows: 1;word-spacing: 1px;background-color: rgb(255, 255, 255);color: rgb(34, 34, 34);letter-spacing: 0.544px;caret-color: rgb(34, 34, 34);text-size-adjust: inherit;line-height: 1.75em;visibility: visible;font-family: system-ui, -apple-system, 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="outline: 0px;max-width: 100%;font-size: 20px;visibility: visible;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Apple Color Emoji", "Emoji Symbols Font", "Segoe UI Symbol", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"><strong style="outline: 0px;max-width: 100%;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;">二、架构演变</strong></span></p> <section style="outline: 0px;max-width: 100%;font-size: 16px;white-space: normal;widows: 1;word-spacing: 1px;color: rgb(34, 34, 34);letter-spacing: 0.544px;background-color: rgb(255, 255, 255);caret-color: rgb(34, 34, 34);text-size-adjust: inherit;text-align: center;line-height: 1.75em;visibility: visible;font-family: system-ui, -apple-system, 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;"> <img class="rich_pages wxw-img" data-ratio="0.5722222222222222" data-s="300,640" data-type="png" data-w="1080" style="outline: 0px;box-sizing: border-box;width: 677px;overflow-wrap: break-word !important;visibility: visible !important;height: auto !important;" src="/upload/7207f6e026280c593b2400a017dde90e.png"> </section> <section style="outline: 0px;max-width: 100%;font-size: 16px;text-align: left;white-space: normal;widows: 1;word-spacing: 1px;color: rgb(34, 34, 34);letter-spacing: 0.544px;background-color: rgb(255, 255, 255);caret-color: rgb(34, 34, 34);text-size-adjust: inherit;line-height: 1.75em;visibility: visible;font-family: system-ui, -apple-system, 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="outline: 0px;max-width: 100%;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Apple Color Emoji", "Emoji Symbols Font", "Segoe UI Symbol", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;">从图中已经可以很容易看出架构的演进过程,通过对三个层的举例来进行说明:</span> </section> <section style="outline: 0px;max-width: 100%;font-size: 16px;text-align: left;white-space: normal;widows: 1;word-spacing: 1px;color: rgb(34, 34, 34);letter-spacing: 0.544px;background-color: rgb(255, 255, 255);caret-color: rgb(34, 34, 34);text-size-adjust: inherit;line-height: 1.75em;visibility: visible;font-family: system-ui, -apple-system, 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="outline: 0px;max-width: 100%;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Apple Color Emoji", "Emoji Symbols Font", "Segoe UI Symbol", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"><strong style="outline: 0px;max-width: 100%;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;">SAAS</strong>:比如我们最早的就是单体应用,多个业务之间可能都没有进行分层,之后我们业务多了,都各自混淆在一起,后来我们就通过MVC、SSM、分层等方式进行业务拆分,保证业务与业务之间解耦</span> </section> <section style="outline: 0px;max-width: 100%;font-size: 16px;text-align: left;white-space: normal;widows: 1;word-spacing: 1px;color: rgb(34, 34, 34);letter-spacing: 0.544px;background-color: rgb(255, 255, 255);caret-color: rgb(34, 34, 34);text-size-adjust: inherit;line-height: 1.75em;font-family: system-ui, -apple-system, 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="outline: 0px;max-width: 100%;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Apple Color Emoji", "Emoji Symbols Font", "Segoe UI Symbol", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"><strong style="outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">PAAS</strong>:随者业务的增长,我们打算分离出一个子系统,但是成本太高,每次都需要从头搭建一个子系统,效率低下。这时我们就抽取除了一些通用技术,比如mesh、SOA、微服务等方式来隔离系统,且对通用技术复用来快速搭建一个系统</span> </section> <section style="outline: 0px;max-width: 100%;font-size: 16px;text-align: left;white-space: normal;widows: 1;word-spacing: 1px;color: rgb(34, 34, 34);letter-spacing: 0.544px;background-color: rgb(255, 255, 255);caret-color: rgb(34, 34, 34);text-size-adjust: inherit;line-height: 1.75em;font-family: system-ui, -apple-system, 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="outline: 0px;max-width: 100%;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Apple Color Emoji", "Emoji Symbols Font", "Segoe UI Symbol", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"><strong style="outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">IAAS</strong>:比如订单服务并发量高,单台服务器已经无法满足要求,这时我们需要多台服务器,可能有windows的、linux、mac,想要快速部署就需要屏蔽OS,于是就有了VM、Docker、K8S等技术来屏蔽OS</span> </section> <section style="outline: 0px;max-width: 100%;font-size: 16px;text-align: left;white-space: normal;widows: 1;word-spacing: 1px;color: rgb(34, 34, 34);letter-spacing: 0.544px;background-color: rgb(255, 255, 255);caret-color: rgb(34, 34, 34);text-size-adjust: inherit;line-height: 1.75em;font-family: system-ui, -apple-system, 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;"> <br style="outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"> </section> <section style="outline: 0px;max-width: 100%;font-size: 16px;text-align: left;white-space: normal;widows: 1;word-spacing: 1px;color: rgb(34, 34, 34);letter-spacing: 0.544px;background-color: rgb(255, 255, 255);caret-color: rgb(34, 34, 34);text-size-adjust: inherit;line-height: 1.75em;font-family: system-ui, -apple-system, 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="outline: 0px;max-width: 100%;font-size: 20px;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Apple Color Emoji", "Emoji Symbols Font", "Segoe UI Symbol", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"><strong style="outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">三、限界上下文</strong></span> </section> <section style="outline: 0px;max-width: 100%;font-size: 16px;text-align: left;white-space: normal;widows: 1;word-spacing: 1px;color: rgb(34, 34, 34);letter-spacing: 0.544px;background-color: rgb(255, 255, 255);caret-color: rgb(34, 34, 34);text-size-adjust: inherit;line-height: 1.75em;font-family: system-ui, -apple-system, 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="outline: 0px;max-width: 100%;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Apple Color Emoji", "Emoji Symbols Font", "Segoe UI Symbol", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"><strong style="outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">限界上下文概念</strong></span> </section> <section style="outline: 0px;max-width: 100%;font-size: 16px;white-space: normal;widows: 1;word-spacing: 1px;color: rgb(34, 34, 34);letter-spacing: 0.544px;background-color: rgb(255, 255, 255);caret-color: rgb(34, 34, 34);text-size-adjust: inherit;text-align: center;line-height: 1.75em;font-family: system-ui, -apple-system, 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;"> <img class="rich_pages wxw-img" data-ratio="0.5231481481481481" data-s="300,640" data-type="png" data-w="1080" style="outline: 0px;box-sizing: border-box;width: 677px;overflow-wrap: break-word !important;visibility: visible !important;height: auto !important;" src="/upload/96b4cf1d2d22302d194702c6c5e2d7cc.png"> </section> <section style="outline: 0px;max-width: 100%;font-size: 16px;text-align: left;white-space: normal;widows: 1;word-spacing: 1px;color: rgb(34, 34, 34);letter-spacing: 0.544px;background-color: rgb(255, 255, 255);caret-color: rgb(34, 34, 34);text-size-adjust: inherit;line-height: 1.75em;font-family: system-ui, -apple-system, 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="outline: 0px;max-width: 100%;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Apple Color Emoji", "Emoji Symbols Font", "Segoe UI Symbol", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"><strong style="outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">BC与业务的关系</strong>:</span> </section> <section style="outline: 0px;max-width: 100%;font-size: 16px;text-align: left;white-space: normal;widows: 1;word-spacing: 1px;color: rgb(34, 34, 34);letter-spacing: 0.544px;background-color: rgb(255, 255, 255);caret-color: rgb(34, 34, 34);text-size-adjust: inherit;line-height: 1.75em;font-family: system-ui, -apple-system, 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="outline: 0px;max-width: 100%;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Apple Color Emoji", "Emoji Symbols Font", "Segoe UI Symbol", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;">通过对业务的划分,比如订单系统,订单是一个子域;库存是一个子域;</span> </section> <section style="outline: 0px;max-width: 100%;font-size: 16px;text-align: left;white-space: normal;widows: 1;word-spacing: 1px;color: rgb(34, 34, 34);letter-spacing: 0.544px;background-color: rgb(255, 255, 255);caret-color: rgb(34, 34, 34);text-size-adjust: inherit;line-height: 1.75em;font-family: system-ui, -apple-system, 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="outline: 0px;max-width: 100%;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Apple Color Emoji", "Emoji Symbols Font", "Segoe UI Symbol", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;">其中商品再不同的子域中所表示的意义也不同,比如在订单上下文中的商品表示商品的单价、折扣等等;而在库存的上下文中商品表示商品的库存量、成本、存放位置等。</span> </section> <section style="outline: 0px;max-width: 100%;font-size: 16px;text-align: left;white-space: normal;widows: 1;word-spacing: 1px;color: rgb(34, 34, 34);letter-spacing: 0.544px;background-color: rgb(255, 255, 255);caret-color: rgb(34, 34, 34);text-size-adjust: inherit;line-height: 1.75em;font-family: system-ui, -apple-system, 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="outline: 0px;max-width: 100%;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Apple Color Emoji", "Emoji Symbols Font", "Segoe UI Symbol", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"><strong style="outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">BC与技术的关系</strong>:</span> </section> <section style="outline: 0px;max-width: 100%;font-size: 16px;text-align: left;white-space: normal;widows: 1;word-spacing: 1px;color: rgb(34, 34, 34);letter-spacing: 0.544px;background-color: rgb(255, 255, 255);caret-color: rgb(34, 34, 34);text-size-adjust: inherit;line-height: 1.75em;font-family: system-ui, -apple-system, 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="outline: 0px;max-width: 100%;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Apple Color Emoji", "Emoji Symbols Font", "Segoe UI Symbol", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;">多个子域之间必须需要在应用层进行聚合,而聚合的过程中就引出了技术方案,比如订单到库存到支付,他们应该采用同步方式;这几个子域调用通知都应该是异步,那么可能就需要消息中间件或其它技术方案</span> </section> <pre mp-original-font-size="17" mp-original-line-height="25.600000381469727" style="outline: 0px;max-width: 100%;color: rgb(0, 0, 0);font-size: 16px;text-align: left;widows: 1;word-spacing: 1px;caret-color: rgb(51, 51, 51);letter-spacing: 0.544px;overflow: auto;background-color: rgb(255, 255, 255);text-size-adjust: inherit;line-height: 25.6px;visibility: visible;font-family: -apple-system, system-ui, "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;"><p mp-original-font-size="17" mp-original-line-height="25.600000381469727" style="margin-right: 8px;margin-left: 8px;outline: 0px;max-width: 100%;text-align: center;color: rgb(34, 34, 34);letter-spacing: 0.544px;visibility: visible;line-height: 25.6px;font-family: -apple-system, 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;"><br style="outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></p><p mp-original-font-size="17" mp-original-line-height="25.600000381469727" style="margin-right: 8px;margin-left: 8px;outline: 0px;max-width: 100%;text-align: center;color: rgb(34, 34, 34);letter-spacing: 0.544px;visibility: visible;line-height: 25.6px;font-family: -apple-system, 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;"><br style="outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></p></pre> <section style="outline: 0px;max-width: 100%;font-size: 16px;text-align: left;white-space: normal;widows: 1;word-spacing: 1px;color: rgb(34, 34, 34);letter-spacing: 0.544px;background-color: rgb(255, 255, 255);caret-color: rgb(34, 34, 34);text-size-adjust: inherit;line-height: 1.75em;font-family: system-ui, -apple-system, 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="outline: 0px;max-width: 100%;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Apple Color Emoji", "Emoji Symbols Font", "Segoe UI Symbol", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"><strong style="outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">限界上下文划分规则</strong></span> </section> <section style="outline: 0px;max-width: 100%;font-size: 16px;white-space: normal;widows: 1;word-spacing: 1px;color: rgb(34, 34, 34);letter-spacing: 0.544px;background-color: rgb(255, 255, 255);caret-color: rgb(34, 34, 34);text-size-adjust: inherit;text-align: center;line-height: 1.75em;font-family: system-ui, -apple-system, 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;"> <img class="rich_pages wxw-img" data-ratio="0.31409544950055496" data-s="300,640" data-type="png" data-w="901" style="outline: 0px;box-sizing: border-box;width: 677px;overflow-wrap: break-word !important;visibility: visible !important;height: auto !important;" src="/upload/1bdeb6aec1a765e475c8a26fa91a19c9.png"> </section> <section style="outline: 0px;max-width: 100%;font-size: 16px;text-align: left;white-space: normal;widows: 1;word-spacing: 1px;color: rgb(34, 34, 34);letter-spacing: 0.544px;background-color: rgb(255, 255, 255);caret-color: rgb(34, 34, 34);text-size-adjust: inherit;line-height: 1.75em;font-family: system-ui, -apple-system, 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="outline: 0px;max-width: 100%;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Apple Color Emoji", "Emoji Symbols Font", "Segoe UI Symbol", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;">一般来说,先考虑团队规模,来决定最终需要划分到多细粒度的BC,如果团队规模过小而BC过细,则对后期的运维、部署、上线都会造成很大的负担;</span> </section> <section style="outline: 0px;max-width: 100%;font-size: 16px;text-align: left;white-space: normal;widows: 1;word-spacing: 1px;color: rgb(34, 34, 34);letter-spacing: 0.544px;background-color: rgb(255, 255, 255);caret-color: rgb(34, 34, 34);text-size-adjust: inherit;line-height: 1.75em;font-family: system-ui, -apple-system, 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="outline: 0px;max-width: 100%;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Apple Color Emoji", "Emoji Symbols Font", "Segoe UI Symbol", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;">在确定好粒度后,可以对语义相关性、功能相关性-业务方向、功能相关性-非业务方向进行划分</span> </section> <section style="outline: 0px;max-width: 100%;font-size: 16px;text-align: left;white-space: normal;widows: 1;word-spacing: 1px;color: rgb(34, 34, 34);letter-spacing: 0.544px;background-color: rgb(255, 255, 255);caret-color: rgb(34, 34, 34);text-size-adjust: inherit;line-height: 1.75em;font-family: system-ui, -apple-system, 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="outline: 0px;max-width: 100%;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Apple Color Emoji", "Emoji Symbols Font", "Segoe UI Symbol", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;">按照以上的规则划分之后就得到了多个BC啦</span> </section> <section style="margin-top: 16px;outline: 0px;max-width: 100%;font-size: 16px;text-align: left;white-space: normal;widows: 1;word-spacing: 1px;color: rgb(34, 34, 34);letter-spacing: 0.544px;background-color: rgb(255, 255, 255);caret-color: rgb(34, 34, 34);text-size-adjust: inherit;line-height: 1.75em;font-family: system-ui, -apple-system, 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="outline: 0px;max-width: 100%;color: rgb(49, 133, 155);font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Apple Color Emoji", "Emoji Symbols Font", "Segoe UI Symbol", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"><strong style="outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">一个BC代表一个微服务吗?</strong></span> </section> <section style="outline: 0px;max-width: 100%;font-size: 16px;white-space: normal;widows: 1;word-spacing: 1px;color: rgb(34, 34, 34);letter-spacing: 0.544px;background-color: rgb(255, 255, 255);caret-color: rgb(34, 34, 34);text-size-adjust: inherit;text-align: center;line-height: 1.75em;font-family: system-ui, -apple-system, 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;"> <img class="rich_pages wxw-img" data-ratio="0.351931330472103" data-s="300,640" data-type="png" data-w="932" style="outline: 0px;box-sizing: border-box;width: 677px;overflow-wrap: break-word !important;visibility: visible !important;height: auto !important;" src="/upload/1d9d6ff8132e2b40c8233dc5df42103e.png"> </section> <section style="outline: 0px;max-width: 100%;font-size: 16px;text-align: left;white-space: normal;widows: 1;word-spacing: 1px;color: rgb(34, 34, 34);letter-spacing: 0.544px;background-color: rgb(255, 255, 255);caret-color: rgb(34, 34, 34);text-size-adjust: inherit;line-height: 1.75em;font-family: system-ui, -apple-system, 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="outline: 0px;max-width: 100%;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Apple Color Emoji", "Emoji Symbols Font", "Segoe UI Symbol", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"><strong style="outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">概念</strong>:微服务一般是指将高度相关功能的一个开发部署单元,有自己的技术自治性、技术选型、弹性扩缩容、发布上下频率等,说白了就是各自维护一个业务,然后多个业务组成一个系统,多个业务之间各自管理</span> </section> <section style="outline: 0px;max-width: 100%;font-size: 16px;text-align: left;white-space: normal;widows: 1;word-spacing: 1px;color: rgb(34, 34, 34);letter-spacing: 0.544px;background-color: rgb(255, 255, 255);caret-color: rgb(34, 34, 34);text-size-adjust: inherit;line-height: 1.75em;font-family: system-ui, -apple-system, 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="outline: 0px;max-width: 100%;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Apple Color Emoji", "Emoji Symbols Font", "Segoe UI Symbol", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"><strong style="outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">关系:</strong>这里的BC其实就是一个领域或一个模块或一个业务,如果两个领域相关性很高,就可以包含多个BC,或者如果一个领域访问量非常大,则需要部署在一个微服务中以提高性能</span> </section> <p style="margin-bottom: 20px;outline: 0px;max-width: 100%;font-size: 16px;white-space: normal;widows: 1;word-spacing: 1px;background-color: rgb(255, 255, 255);color: rgb(34, 34, 34);letter-spacing: 0.544px;caret-color: rgb(34, 34, 34);text-size-adjust: inherit;line-height: 1.75em;font-family: system-ui, -apple-system, 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="outline: 0px;max-width: 100%;font-size: 20px;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Apple Color Emoji", "Emoji Symbols Font", "Segoe UI Symbol", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"><strong style="outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">四、领域驱动设计的四重边界</strong></span></p> <section style="outline: 0px;max-width: 100%;font-size: 16px;white-space: normal;widows: 1;word-spacing: 1px;color: rgb(34, 34, 34);letter-spacing: 0.544px;background-color: rgb(255, 255, 255);caret-color: rgb(34, 34, 34);text-size-adjust: inherit;text-align: center;line-height: 1.75em;font-family: system-ui, -apple-system, 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;"> <img class="rich_pages wxw-img" data-ratio="1.099074074074074" data-s="300,640" data-type="png" data-w="1080" style="outline: 0px;box-sizing: border-box;width: 677px;overflow-wrap: break-word !important;visibility: visible !important;height: auto !important;" src="/upload/1c3978c15a28095167ddc29a5d07a259.png"> </section> <section style="outline: 0px;max-width: 100%;font-size: 16px;text-align: left;white-space: normal;widows: 1;word-spacing: 1px;color: rgb(34, 34, 34);letter-spacing: 0.544px;background-color: rgb(255, 255, 255);caret-color: rgb(34, 34, 34);text-size-adjust: inherit;line-height: 1.75em;font-family: system-ui, -apple-system, 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="outline: 0px;max-width: 100%;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Apple Color Emoji", "Emoji Symbols Font", "Segoe UI Symbol", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;">根据上图所示,我们通过<span style="outline: 0px;max-width: 100%;color: rgb(49, 133, 155);box-sizing: border-box !important;overflow-wrap: break-word !important;">四重来进行架构设计</span>:</span> </section> <section style="outline: 0px;max-width: 100%;font-size: 16px;text-align: left;white-space: normal;widows: 1;word-spacing: 1px;color: rgb(34, 34, 34);letter-spacing: 0.544px;background-color: rgb(255, 255, 255);caret-color: rgb(34, 34, 34);text-size-adjust: inherit;line-height: 1.75em;font-family: system-ui, -apple-system, 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="outline: 0px;max-width: 100%;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Apple Color Emoji", "Emoji Symbols Font", "Segoe UI Symbol", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"><strong style="outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">分而治之</strong>:DDD通过规划四重边界,把领域知识做了合理的固化和分层。业务有核心领域和支持域、业务域中又拆分成多个限界上下文(BC),一个BC中又根据领域知识核心与否进行分层,领域层中按照多个业务(子域)的强相关性进行聚合成一个子域。另外,搜索公众号后端架构师后台回复“架构整洁”,获取一份惊喜礼包。</span> </section> <section style="outline: 0px;max-width: 100%;font-size: 16px;text-align: left;white-space: normal;widows: 1;word-spacing: 1px;color: rgb(34, 34, 34);letter-spacing: 0.544px;background-color: rgb(255, 255, 255);caret-color: rgb(34, 34, 34);text-size-adjust: inherit;line-height: 1.75em;font-family: system-ui, -apple-system, 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="outline: 0px;max-width: 100%;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Apple Color Emoji", "Emoji Symbols Font", "Segoe UI Symbol", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;">【第一重边界】确定项目的愿景与目标,确定问题空间,确定核心子领域、通用子领域(多个子领域可以复用)、支撑子领域(额外功能,如数据统计、导出报表)</span> </section> <section style="outline: 0px;max-width: 100%;font-size: 16px;text-align: left;white-space: normal;widows: 1;word-spacing: 1px;color: rgb(34, 34, 34);letter-spacing: 0.544px;background-color: rgb(255, 255, 255);caret-color: rgb(34, 34, 34);text-size-adjust: inherit;line-height: 1.75em;font-family: system-ui, -apple-system, 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="outline: 0px;max-width: 100%;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Apple Color Emoji", "Emoji Symbols Font", "Segoe UI Symbol", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;">【第二重边界】解决方案空间里的限界上下文就是一道进程隔离层面的物理边界</span> </section> <section style="outline: 0px;max-width: 100%;font-size: 16px;text-align: left;white-space: normal;widows: 1;word-spacing: 1px;color: rgb(34, 34, 34);letter-spacing: 0.544px;background-color: rgb(255, 255, 255);caret-color: rgb(34, 34, 34);text-size-adjust: inherit;line-height: 1.75em;font-family: system-ui, -apple-system, 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="outline: 0px;max-width: 100%;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Apple Color Emoji", "Emoji Symbols Font", "Segoe UI Symbol", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;">【第三重边界】每个限界上下文内,使用分层架构划分为:接口层、领域层、应用层、基础设施层之间的最小隔离</span> </section> <section style="outline: 0px;max-width: 100%;font-size: 16px;text-align: left;white-space: normal;widows: 1;word-spacing: 1px;color: rgb(34, 34, 34);letter-spacing: 0.544px;background-color: rgb(255, 255, 255);caret-color: rgb(34, 34, 34);text-size-adjust: inherit;line-he
作者:じ☆ve不哭
> mysqldump备份的表结构(可参考[https://studyjava.cn/post/1696](https://studyjava.cn/post/1696)),恢复到数据库中 ``` package cv.datacenter.etl; import java.io.*; import java.util.List; import cn.hutool.core.io.FileUtil; import cn.hutool.core.util.ZipUtil; /** * @author zsljava * @date 2022年04月29日 4:01 * @description TODO */ public class MySQLDump { private static String MYSQL_HOST = "192.168.1.24"; private static String MYSQL_NAME = "root"; private static String MYSQL_PWD = "root"; private static String MYSQL_PORT = "3306"; public static void main(String[] args) throws IOException, InterruptedException { File[] ls = FileUtil.ls("C:\\Users\\zsljava\\Desktop\\dbback"); String sql = "D:\\Develop\\Tool\\phpstudy_pro\\Extensions\\MySQL5.7.26\\bin\\mysql -u"+MYSQL_NAME+" -h"+MYSQL_HOST+" -P"+MYSQL_PORT+" -p"+MYSQL_PWD+" < "; for (File f:ls) { if(f.isDirectory()){ continue; } File unzip = ZipUtil.unzip(f); List<File> files = FileUtil.loopFiles(unzip); for (File file : files) { // System.out.println(sql + file.getAbsolutePath()); String cmd = sql + file.getAbsolutePath(); // String[] command = { "cmd", "/c", cmd}; Process process = Runtime.getRuntime().exec("cmd.exe /c " + cmd); // 输出结果,必须写在 waitFor 之前 String outStr = getStreamStr(process.getInputStream()); // 错误结果,必须写在 waitFor 之前 String errStr = getStreamStr(process.getErrorStream()); int exitValue = process.waitFor(); // 退出值 0 为正常,其他为异常 System.out.println("exitValue: " + exitValue); System.out.println("outStr: " + outStr); System.out.println("errStr: " + errStr); System.out.println("执行完成 = " + cmd); } } } public static String getStreamStr(InputStream is) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(is, "GBK")); StringBuilder sb = new StringBuilder(); String line; while ((line = br.readLine()) != null) { sb.append(line); sb.append("\n"); } br.close(); return sb.toString(); } } ```
作者:微信小助手
<section data-tool="mdnice编辑器" data-website="https://www.mdnice.com" style="font-size: 16px;color: black;padding-right: 10px;padding-left: 10px;line-height: 1.6;letter-spacing: 0px;word-break: break-word;text-align: left;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;margin-bottom: 24px;" data-mpa-powered-by="yiban.io"> <h2 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;border-bottom: 2px solid rgb(239, 112, 96);font-size: 1.3em;"><span style="display: none;"></span><span style="display: inline-block;background: rgb(239, 112, 96);color: rgb(255, 255, 255);padding: 3px 10px 1px;border-top-right-radius: 3px;border-top-left-radius: 3px;margin-right: 3px;">1. 什么是数据库事务?</span><span style="display: inline-block;vertical-align: bottom;border-bottom: 36px solid #efebe9;border-right: 20px solid transparent;"> </span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">事务,由一个<strong>有限的数据库操作序列</strong>构成,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位。</p> <blockquote data-tool="mdnice编辑器" style="border-top: none;border-right: none;border-bottom: none;font-size: 0.9em;overflow: auto;color: rgb(106, 115, 125);padding: 10px 10px 10px 20px;margin-bottom: 20px;margin-top: 20px;border-left-color: rgb(239, 112, 96);background: rgb(255, 249, 249);"> <p style="font-size: 16px;padding-top: 8px;padding-bottom: 8px;color: black;line-height: 26px;">假如A转账给B 100 元,先从A的账户里扣除 100 元,再在 B 的账户上加上 100 元。如果扣完A的100元后,还没来得及给B加上,银行系统异常了,最后导致A的余额减少了,B的余额却没有增加。所以就需要<strong>事务</strong>,将A的钱回滚回去,就是这么简单。</p> </blockquote> <h2 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;border-bottom: 2px solid rgb(239, 112, 96);font-size: 1.3em;"><span style="display: none;"></span><span style="display: inline-block;background: rgb(239, 112, 96);color: rgb(255, 255, 255);padding: 3px 10px 1px;border-top-right-radius: 3px;border-top-left-radius: 3px;margin-right: 3px;">2. 事务的四大特性</span><span style="display: inline-block;vertical-align: bottom;border-bottom: 36px solid #efebe9;border-right: 20px solid transparent;"> </span></h2> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.744408945686901" src="/upload/e96d246372db5e322d08002fc50437d3.png" data-type="png" data-w="626" style="display: block;margin-right: auto;margin-left: auto;"> </figure> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> 原子性:事务作为一个整体被执行,包含在其中的对数据库的操作要么全部都执行,要么都不执行。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> 一致性:指在事务开始之前和事务结束以后,数据不会被破坏,假如A账户给B账户转10块钱,不管成功与否,A和B的总金额是不变的。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> 隔离性:多个事务并发访问时,事务之间是相互隔离的,一个事务不应该被其他事务干扰,多个并发事务之间要相互隔离。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> 持久性:表示事务完成提交后,该事务对数据库所作的操作更改,将持久地保存在数据库之中。 </section></li> </ul> <h2 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;border-bottom: 2px solid rgb(239, 112, 96);font-size: 1.3em;"><span style="display: none;"></span><span style="display: inline-block;background: rgb(239, 112, 96);color: rgb(255, 255, 255);padding: 3px 10px 1px;border-top-right-radius: 3px;border-top-left-radius: 3px;margin-right: 3px;">3. 事务的隔离级别有哪些?MySQL的默认隔离级别是什么?</span><span style="display: inline-block;vertical-align: bottom;border-bottom: 36px solid #efebe9;border-right: 20px solid transparent;"> </span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">事务的隔离级别有四种,分别是:读未提交(Read Uncommitted)、读已提交(Read Committed)、可重复读(Repeatable Read)、串行化(Serializable)。</p> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <strong style="color: black;">读未提交隔离级别</strong>:只限制了两个数据不能同时修改,但是修改数据的时候,即使事务未提交,都是可以被别的事务读取到的,这级别的事务隔离有脏读、重复读、幻读的问题; </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <strong style="color: black;">读已提交隔离级别</strong>:当前事务只能读取到其他事务提交的数据,所以这种事务的隔离级别解决了脏读问题,但还是会存在重复读、幻读问题; </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <strong style="color: black;">可重复读:</strong> 可重复读隔离级别,限制了读取数据的时候,不可以进行修改,所以解决了重复读的问题,但是读取范围数据的时候,是可以插入数据,所以还会存在幻读问题; </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <strong style="color: black;">串行化:</strong> 事务最高的隔离级别,在该级别下,所有事务都是进行串行化顺序执行的。可以避免脏读、不可重复读与幻读所有并发问题。但是这种事务隔离级别下,事务执行很耗性能。 </section></li> </ul> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">Mysql默认的事务隔离级别是<strong>可重复读</strong>(RR)。</p> <h2 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;border-bottom: 2px solid rgb(239, 112, 96);font-size: 1.3em;"><span style="display: none;"></span><span style="display: inline-block;background: rgb(239, 112, 96);color: rgb(255, 255, 255);padding: 3px 10px 1px;border-top-right-radius: 3px;border-top-left-radius: 3px;margin-right: 3px;">4. Mysql为什么选择RR作为默认隔离级别?</span><span style="display: inline-block;vertical-align: bottom;border-bottom: 36px solid #efebe9;border-right: 20px solid transparent;"> </span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">我们知道Mysql有四种数据库隔离级别,分别是<strong>读未提交、读已提交、可重复读、串行化</strong>。而读未提交隔离级别太低了,<strong>会有脏读问题</strong>,串行化隔离级别太高了,<strong>会影响并发读</strong>。那么就剩下读已提交(RC)和可重复读(RR)了。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">那么,<strong>Mysql为什么会选择RR作为默认隔离级别呢?</strong></p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">我们的MySQL数据库一般都是集群部署的,会有主库、从库。主库负责写,从库负责读。主库写入之后,会进行主从复制,把数据同步到从库。</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.46944444444444444" src="/upload/f188a7d586609d1a6cfe7bad82449e69.png" data-type="png" data-w="1080" style="display: block;margin-right: auto;margin-left: auto;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">从库是在主库拿到bin log日志,并执行bin log,从而保证从库与主库的数据一致性。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">实际上,<code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">bin log</code>有三种格式,分别是<code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">statement,row和mixed</code>。如果是<code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">statement</code>格式,<code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">bin log</code>记录的是<code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">SQL</code>的<strong>原文</strong>。Mysql早些时候,<code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">bin log</code>日志格式只有<code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">statement</code>这种,在RC的隔离级别,可能出现数据不一致的问题。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">MySQL官网上还记录了这个bug。</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.24351851851851852" src="/upload/2a7e2843789199e38e434b8c5dcc03e7.png" data-type="png" data-w="1080" style="display: block;margin-right: auto;margin-left: auto;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">我们可以复现这个bug,假设有表结构如下:</p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><span style="display: block;background: url("https://mmbiz.qpic.cn/mmbiz_svg/eytJa9K5jko47W2yKibuVoA9cXGozdZDdEYk10qAAIPfaOxVL5ooXI8XtrQYNH7iaJswcXesuibAqQCeIlluCEkGRZw6O0M5lg2/640?wx_fmt=svg") 10px 10px / 40px no-repeat rgb(39, 40, 34);height: 30px;width: 100%;margin-bottom: -7px;border-radius: 5px;"></span><code style="overflow-x: auto;padding: 16px;color: #ddd;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;font-size: 12px;-webkit-overflow-scrolling: touch;padding-top: 15px;background: #272822;border-radius: 5px;"> CREATE TABLE t (<br> a int(11) DEFAULT NULL,<br> b int(11) DEFAULT NULL,<br> KEY a (a)<br> ) ENGINE=InnoDB DEFAULT CHARSET=latin1;<br></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">插入两条数据</p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><span style="display: block;background: url("https://mmbiz.qpic.cn/mmbiz_svg/eytJa9K5jko47W2yKibuVoA9cXGozdZDdEYk10qAAIPfaOxVL5ooXI8XtrQYNH7iaJswcXesuibAqQCeIlluCEkGRZw6O0M5lg2/640?wx_fmt=svg") 10px 10px / 40px no-repeat rgb(39, 40, 34);height: 30px;width: 100%;margin-bottom: -7px;border-radius: 5px;"></span><code style="overflow-x: auto;padding: 16px;color: #ddd;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;font-size: 12px;-webkit-overflow-scrolling: touch;padding-top: 15px;background: #272822;border-radius: 5px;">insert into t values(666,2),(233,1);<br></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">执行以下这两个事务:</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.29907407407407405" src="/upload/4c037a64a2292c56f0ad4795255e834d.png" data-type="png" data-w="1080" style="display: block;margin-right: auto;margin-left: auto;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">执行完之后,因为
作者:微信小助手
<section style="margin-top: 20px;outline: 0px;max-width: 100%;font-family: -apple-system, system-ui, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-align: left;visibility: visible;margin-bottom: 16px;box-sizing: border-box !important;overflow-wrap: break-word !important;" data-mpa-powered-by="yiban.io"> <span style="background-color: rgb(255, 255, 255);color: rgb(53, 53, 53);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.8px;text-align: left;word-spacing: 0.8px;">大家好,我是飘渺。</span> </section> <section style="margin-top: 20px;outline: 0px;max-width: 100%;font-family: -apple-system, system-ui, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-align: left;visibility: visible;margin-bottom: 16px;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <span style="background-color: rgb(255, 255, 255);color: rgb(53, 53, 53);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.8px;text-align: left;word-spacing: 0.8px;">今天这篇文章介绍一下数据库的版本管理、迁移工具Flyway</span> </section> <h2 data-tool="mdnice编辑器" style="margin-top: 20px;margin-right: 10px;outline: 0px;font-weight: bold;font-size: 22px;max-width: 100%;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, 'PingFang SC', Cambria, Cochin, Georgia, Times, 'Times New Roman', serif;letter-spacing: 0.8px;text-align: left;white-space: normal;word-spacing: 0.8px;background-color: rgb(255, 255, 255);color: black;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="padding-left: 10px;outline: 0px;max-width: 100%;font-size: 18px;color: rgb(34, 34, 34);display: inline-block;border-left: 5px solid rgb(248, 57, 41);visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;">什么是Flyway? 要解决什么问题?</span></h2> <p data-tool="mdnice编辑器" style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 8px;padding-bottom: 8px;outline: 0px;max-width: 100%;color: rgb(53, 53, 53);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.8px;text-align: left;white-space: normal;word-spacing: 0.8px;background-color: rgb(255, 255, 255);line-height: 1.75;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;">Flyway是一款数据库迁移(migration)工具。简单点说,就是在你部署应用的时候,帮你执行数据库脚本的工具。</p> <p data-tool="mdnice编辑器" style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 8px;padding-bottom: 8px;outline: 0px;max-width: 100%;
作者:じ☆ve不哭
> 启动springboot后会有基于logback default的配置日志输出,这段日志没有采用我们统一的日志格式,是logback内部加载的日志过程,那我们怎么关闭它呢? ### 日志内容 ``` 18:41:09,637 |-INFO in ch.qos.logback.classic.LoggerContext[default] - This is logback-classic version 1.4.7 18:41:09,658 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback-test.xml] 18:41:09,659 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.xml] 18:41:13,071 |-INFO in ch.qos.logback.classic.BasicConfigurator@35beb15e - Setting up default configuration. 18:41:14,614 |-INFO in ch.qos.logback.core.joran.util.ConfigurationWatchListUtil@41fe9859 - Adding [jar:file:/D:/Develop/Tool/mavenjar/org/springframework/boot/spring-boot/3.0.6/spring-boot-3.0.6.jar!/org/springframework/boot/logging/logback/defaults.xml] to configuration watch list. 18:41:14,614 |-INFO in ch.qos.logback.core.joran.spi.ConfigurationWatchList@5ac86ba5 - URL [jar:file:/D:/Develop/Tool/mavenjar/org/springframework/boot/spring-boot/3.0.6/spring-boot-3.0.6.jar!/org/springframework/boot/logging/logback/defaults.xml] is not of type file 18:41:14,616 |-INFO in ch.qos.logback.core.joran.action.ConversionRuleAction - registering conversion word clr with class [org.springframework.boot.logging.logback.ColorConverter] 18:41:14,617 |-INFO in ch.qos.logback.core.joran.action.ConversionRuleAction - registering conversion word wex with class [org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter] 18:41:14,617 |-INFO in ch.qos.logback.core.joran.action.ConversionRuleAction - registering conversion word wEx with class [org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter] 18:41:14,618 |-INFO in ch.qos.logback.core.joran.util.ConfigurationWatchListUtil@41fe9859 - Adding [jar:file:/D:/Develop/Tool/mavenjar/org/springframework/boot/spring-boot/3.0.6/spring-boot-3.0.6.jar!/org/springframework/boot/logging/logback/console-appender.xml] to configuration watch list. 18:41:14,618 |-INFO in ch.qos.logback.core.joran.spi.ConfigurationWatchList@5ac86ba5 - URL [jar:file:/D:/Develop/Tool/mavenjar/org/springframework/boot/spring-boot/3.0.6/spring-boot-3.0.6.jar!/org/springframework/boot/logging/logback/console-appender.xml] is not of type file 18:41:14,646 |-INFO in ch.qos.logback.classic.model.processor.LoggerModelHandler - Setting level of logger [org.apache.catalina.startup.DigesterFactory] to ERROR 18:41:14,646 |-INFO in ch.qos.logback.classic.jul.LevelChangePropagator@6c67e137 - Propagating ERROR level on Logger[org.apache.catalina.startup.DigesterFactory] onto the JUL framework 18:41:14,646 |-INFO in ch.qos.logback.classic.model.processor.LoggerModelHandler - Setting level of logger [org.apache.catalina.util.LifecycleBase] to ERROR 18:41:14,646 |-INFO in ch.qos.logback.classic.jul.LevelChangePropagator@6c67e137 - Propagating ERROR level on Logger[org.apache.catalina.util.LifecycleBase] onto the JUL framework 18:41:14,646 |-INFO in ch.qos.logback.classic.model.processor.LoggerModelHandler - Setting level of logger [org.apache.coyote.http11.Http11NioProtocol] to WARN 18:41:14,646 |-INFO in ch.qos.logback.classic.jul.LevelChangePropagator@6c67e137 - Propagating WARN level on Logger[org.apache.coyote.http11.Http11NioProtocol] onto the JUL framework 18:41:14,646 |-INFO in ch.qos.logback.classic.model.processor.LoggerModelHandler - Setting level of logger [org.apache.sshd.common.util.SecurityUtils] to WARN 18:41:14,646 |-INFO in ch.qos.logback.classic.jul.LevelChangePropagator@6c67e137 - Propagating WARN level on Logger[org.apache.sshd.common.util.SecurityUtils] onto the JUL framework 18:41:14,646 |-INFO in ch.qos.logback.classic.model.processor.LoggerModelHandler - Setting level of logger [org.apache.tomcat.util.net.NioSelectorPool] to WARN 18:41:14,646 |-INFO in ch.qos.logback.classic.jul.LevelChangePropagator@6c67e137 - Propagating WARN level on Logger[org.apache.tomcat.util.net.NioSelectorPool] onto the JUL framework 18:41:14,646 |-INFO in ch.qos.logback.classic.model.processor.LoggerModelHandler - Setting level of logger [org.eclipse.jetty.util.component.AbstractLifeCycle] to ERROR 18:41:14,646 |-INFO in ch.qos.logback.classic.jul.LevelChangePropagator@6c67e137 - Propagating ERROR level on Logger[org.eclipse.jetty.util.component.AbstractLifeCycle] onto the JUL framework 18:41:14,646 |-INFO in ch.qos.logback.classic.model.processor.LoggerModelHandler - Setting level of logger [org.hibernate.validator.internal.util.Version] to WARN 18:41:14,646 |-INFO in ch.qos.logback.classic.jul.LevelChangePropagator@6c67e137 - Propagating WARN level on Logger[org.hibernate.validator.internal.util.Version] onto the JUL framework 18:41:14,646 |-INFO in ch.qos.logback.classic.model.processor.LoggerModelHandler - Setting level of logger [org.springframework.boot.actuate.endpoint.jmx] to WARN 18:41:14,646 |-INFO in ch.qos.logback.classic.jul.LevelChangePropagator@6c67e137 - Propagating WARN level on Logger[org.springframework.boot.actuate.endpoint.jmx] onto the JUL framework 18:41:14,647 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - Processing appender named [CONSOLE] 18:41:14,647 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender] 18:41:14,650 |-INFO in ch.qos.logback.core.model.processor.ImplicitModelHandler - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property 18:41:14,662 |-WARN in ch.qos.logback.core.model.processor.AppenderModelHandler - Appender named [debug-file] not referenced. Skipping further processing. 18:41:14,662 |-WARN in ch.qos.logback.core.model.processor.AppenderModelHandler - Appender named [info-file] not referenced. Skipping further processing. 18:41:14,662 |-WARN in ch.qos.logback.core.model.processor.AppenderModelHandler - Appender named [warn-file] not referenced. Skipping further processing. 18:41:14,662 |-WARN in ch.qos.logback.core.model.processor.AppenderModelHandler - Appender named [error-file] not referenced. Skipping further processing. 18:41:14,662 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - Processing appender named [all-file] 18:41:14,662 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - About to instantiate appender of type [ch.qos.logback.core.rolling.RollingFileAppender] 18:41:14,664 |-INFO in ch.qos.logback.core.model.processor.ImplicitModelHandler - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property 18:41:14,669 |-INFO in c.q.l.core.rolling.SizeAndTimeBasedRollingPolicy@747870628 - setting totalSizeCap to 1 GB 18:41:14,669 |-INFO in c.q.l.core.rolling.SizeAndTimeBasedRollingPolicy@747870628 - Archive files will be limited to [20 MB] each. 18:41:14,670 |-INFO in c.q.l.core.rolling.SizeAndTimeBasedRollingPolicy@747870628 - No compression will be used 18:41:14,671 |-INFO in c.q.l.core.rolling.SizeAndTimeBasedRollingPolicy@747870628 - Will use the pattern logs/all/%d{yyyy-MM-dd}/online-plus-%d{yyyy-MM-dd}.%i.all.log for the active file 18:41:14,679 |-INFO in ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP@191ae03f - The date pattern is 'yyyy-MM-dd' from file name pattern 'logs/all/%d{yyyy-MM-dd}/online-plus-%d{yyyy-MM-dd}.%i.all.log'. 18:41:14,679 |-INFO in ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP@191ae03f - Roll-over at midnight. 18:41:14,684 |-INFO in ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP@191ae03f - Setting initial period to 2023-05-10T10:41:07.050Z 18:41:14,686 |-INFO in ch.qos.logback.core.rolling.RollingFileAppender[all-file] - Active log file name: logs/online-plus.all.log 18:41:14,686 |-INFO in ch.qos.logback.core.rolling.RollingFileAppender[all-file] - File property is set to [logs/online-plus.all.log] 18:41:14,687 |-INFO in ch.qos.logback.classic.model.processor.LoggerModelHandler - Setting level of logger [springfox.documentation] to WARN 18:41:14,687 |-INFO in ch.qos.logback.classic.jul.LevelChangePropagator@6c67e137 - Propagating WARN level on Logger[springfox.documentation] onto the JUL framework 18:41:14,688 |-INFO in ch.qos.logback.classic.model.processor.LoggerModelHandler - Setting additivity of logger [springfox.documentation] to true 18:41:14,688 |-INFO in ch.qos.logback.classic.model.processor.LoggerModelHandler - Setting level of logger [com.anglin] to DEBUG 18:41:14,688 |-INFO in ch.qos.logback.classic.jul.LevelChangePropagator@6c67e137 - Propagating DEBUG level on Logger[com.anglin] onto the JUL framework 18:41:14,688 |-INFO in ch.qos.logback.classic.model.processor.LoggerModelHandler - Setting additivity of logger [com.anglin] to true 18:41:14,688 |-INFO in ch.qos.logback.classic.model.processor.LoggerModelHandler - Setting level of logger [io.lettuce.core] to WARN 18:41:14,688 |-INFO in ch.qos.logback.classic.jul.LevelChangePropagator@6c67e137 - Propagating WARN level on Logger[io.lettuce.core] onto the JUL framework 18:41:14,688 |-INFO in ch.qos.logback.classic.model.processor.LoggerModelHandler - Setting additivity of logger [io.lettuce.core] to true 18:41:14,688 |-INFO in ch.qos.logback.classic.model.processor.RootLoggerModelHandler - Setting level of ROOT logger to INFO 18:41:14,688 |-INFO in ch.qos.logback.classic.jul.LevelChangePropagator@6c67e137 - Propagating INFO level on Logger[ROOT] onto the JUL framework 18:41:14,688 |-INFO in ch.qos.logback.core.model.processor.AppenderRefModelHandler - Attaching appender named [CONSOLE] to Logger[ROOT] 18:41:14,688 |-INFO in ch.qos.logback.core.model.processor.AppenderRefModelHandler - Attaching appender named [all-file] to Logger[ROOT] 18:41:14,689 |-INFO in ch.qos.logback.core.model.processor.DefaultProcessor@9635fa - End of configuration. 18:41:14,689 |-INFO in org.springframework.boot.logging.logback.SpringBootJoranConfigurator@53ab0286 - Registering current configuration as safe fallback point ``` ### 解决方案 logback-spring.xml中增加statusListener即可 ``` <configuration> <statusListener class="ch.qos.logback.core.status.NopStatusListener" /> </configuration> ``` ### 源码 
作者:微信小助手
<section data-tool="mdnice编辑器" data-website="https://www.mdnice.com" style="line-height: 1.6;word-break: break-word;text-align: left;padding: 5px;font-size: 16px;color: rgb(53, 53, 53);word-spacing: 0.8px;letter-spacing: 0.8px;border-radius: 16px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;" data-mpa-powered-by="yiban.io"> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">分布式系统中会存在这样的开发场景,不同需求可能涉及到对同一个服务的开发,那么该服务在研发期间就会存在多个版本并行的状态,为了保持不同版本之间的隔离性,验收需要将请求路由到指定版本号的服务上处理;</p> <p><img class="rich_pages wxw-img" data-ratio="0.1718249733191035" data-type="png" data-w="937" style="height: auto !important;" src="/upload/7bababfd9d23fa51ffe2b731dd79cfda.png"></p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">假设存在三个服务:A、B、C,且服务B和C都存在多个版本,那么让请求按照即定的路由规则执行,即可保证研发期间的验收是版本间隔离的,并且可以实现灰度部署的策略;</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">这篇文章只讲理论知识,灰度部署实战篇在陈某前面一篇文章中有介绍,请看:<a href="https://mp.weixin.qq.com/s?__biz=MzU3MDAzNDg1MA==&mid=2247508403&idx=1&sn=be24819cfea40d8c76cc009fb8784e47&chksm=fcf77e7ecb80f768d59716a6af9e6161d994171f08966fbeb7fc0f5b6ac4f0ae5864ac6b781e&scene=21&cur_album_id=2042874937312346114#wechat_redirect" style="color: rgb(248, 57, 41);border-bottom: 1px solid rgb(248, 57, 41);" data-linktype="2">聊聊 Spring Cloud 全链路灰度发布 方案~</a></p> <h2 data-tool="mdnice编辑器" style="font-weight: bold;color: black;font-size: 22px;margin-top: 20px;margin-right: 10px;"><span style="display: none;"></span><span style="font-size: 18px;color: rgb(234, 84, 41);letter-spacing: 0.5444px;padding-bottom: 10px;border-bottom: 2px solid rgb(234, 84, 41);visibility: visible;">负载策略</span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">在微服务系统架构中,请求在服务间转发时会执行负载的策略,尤其当服务存在多版本号的集群模式时,很显然常规的轮询、权重、随机等策略无法满足需求;进行路由规则的自定义设计和开发是常见方式;</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">经典应用场景:在请求发起时,可以通过Header、Cookie、Parameter等不同的方式,携带路由规则的方式与参数执行匹配逻辑,从而将请求路由到指定版本的服务;</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;"><span style="font-weight: 700;color: rgb(248, 57, 41);">默认主分支路由</span></p> <p><img class="rich_pages wxw-img" data-ratio="0.35645677694770544" data-type="png" data-w="937" style="height: auto !important;" src="/upload/fd86006d428886992c1004740e1f4604.png"></p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">通常来说请求会在主干分支上执行,或者其他分支路由规则不匹配,也可以通过标识配置,判断是否由主分支兜底,甚至是存活的任意服务兜底;</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">存活的服务中可能存在多个版本,但是主分支Master是否存活是服务健康与否的基本标志,常规应用中路由规则如果不匹配,会由Master服务进行兜底;</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;"><span style="font-weight: 700;color: rgb(248, 57, 41);">版本号统一路由</span></p> <p><img class="rich_pages wxw-img" data-ratio="0.35645677694770544" data-type="png" data-w="937" style="height: auto !important;" src="/upload/66ceadde564adac67c04f34abfbcfd42.png"></p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">请求通过携带分支号进行统一版本路由是常用的轻量级方案,即如果请求携带的是<code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(255, 93, 108);">2.0.0</code>的分支,则在路由时优先匹配相关版本的服务,不匹配时由Master服务处理即可;</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;"><span style="font-weight: 700;color: rgb(248, 57, 41);">服务定制化路由</span></p> <p><img class="rich_pages wxw-img" data-ratio="0.35645677694770544" data-type="png" data-w="937" style="height: auto !important;" src="/upload/b6795b9fc6bbbbd40477c6e80abc7875.png"></p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">在请求或配置中指定各个服务的路由分支号,也是常见的匹配方案,如上图在请求时指定服务B由<code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(255, 93, 108);">1.0.0</code>分支执行,服务C由<code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(255, 93, 108);">3.0.0</code>分支执行,其余服务在主干分支执行;</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">路由规则可以看做是对可用服务的匹配筛选,如果筛选出来的服务存在集群部署时,还要去执行相应的负载均衡策略,例如上图中当服务C的<code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(255, 93, 108);">3.0.0</code>分支是集群时,路由匹配到该版本后,再通过负载均衡的策略选中其中一个服务处理请求;</p> <h2 data-tool="mdnice编辑器" style="font-weight: bold;color: black;font-size: 22px;margin-top: 20px;margin-right: 10px;"><span style="display: none;"></span><span style="font-size: 18px;color: rgb(234, 84, 41);letter-spacing: 0.5444px;padding-bottom: 10px;border-bottom: 2px solid rgb(234, 84, 41);visibility: visible;">灰度部署</span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">这篇文章只讲理论知识,灰度部署实战篇在陈某前面一篇文章中有介绍,请看:<a href="https://mp.weixin.qq.com/s?__biz=MzU3MDAzNDg1MA==&mid=2247508403&idx=1&sn=be24819cfea40d8c76cc009fb8784e47&chksm=fcf77e7ecb80f768d59716a6af9e6161d994171f08966fbeb7fc0f5b6ac4f0ae5864ac6b781e&scene=21&cur_album_id=2042874937312346114#wechat_redirect" style="color: rgb(248, 57, 41);border-bottom: 1px solid rgb(248, 57, 41);" data-linktype="2">聊聊 Spring Cloud 全链路灰度发布 方案~</a></p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">当负载均衡的策略可以按照定制化开发的规则执行时,那服务的灰度发布就会容易很多,在不影响现有服务的情况下发布新版本,同时将请求按照规则分流,完成对新服务的验收后,替换掉旧版本即可;</p> <p><img class="rich_pages wxw-img" data-ratio="0.37246531483457845" data-type="png" data-w="937" style="height: auto !important;" src="/upload/59004795b23d5bcc3b723cb1c518e69b.png"></p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">分布式系统中子服务的拆分非常多,版本开发通常只会涉及其中部分子服务,通过灰度模式将相关服务部署到线上,并且不会影响主干的服务,只有开启特定的配置才会将请求分流到灰度服务;</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;"><span style="font-weight: 700;color: rgb(248, 57, 41);">流程细节</span></p> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;color: rgb(248, 57, 41);" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(53, 53, 53);"> 1、做好路由配置和管理,请求默认在主干服务执行; </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(53, 53, 53);"> 2、部署版本涉及的相关服务,灰度层面默认不会处理请求; </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(53, 53, 53);"> 3、验收阶段基于配置,将指定规则的请求路由到灰度层; </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(53, 53, 53);"> 4、常用规则:携带分支号、灰度用户群、比例分流、IP等; </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(53, 53, 53);"> 5、完成灰度服务验收后,将相关服务标记为主干服务; </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(53, 53, 53);"> 6、将旧的主干服务下线后,即本次上线流程完整结束; </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(53, 53, 53);"> 7、若发现灰度服务验收失败,撤掉灰度层或修改都可以; </section></li> </ul> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">灰度发布的模式即依赖于自定义的路由规则,以及服务在负载均衡时权重比例倾斜,这些都可以在配置中心管理,在测试时动态修改即可;</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">在这种模式下,灰度服务的上线或者下线几乎是没有明显感知的,如果是相对简单的流程,由测试人员验收灰度层服务即可,如果是复杂的流程,放开一定比例的用户流量,流程观察没有问题后完成升级;</p> <h2 data-tool="mdnice编辑器" style="font-weight: bold;color: black;font-size: 22px;margin-top: 20px;margin-right: 10px;"><span style="display: none;"></span><span style="font-size: 18px;color: rgb(234, 84, 41);letter-spacing: 0.5444px;padding-bottom: 10px;border-bottom: 2px solid rgb(234, 84, 41);visibility: visible;">实践方案</span></h2> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;color: black;font-size: 20px;"><span style="display: none;"></span><span style="font-size: 16px;color: #222;">1、流程设计</span><span style="display: none;"></span></h3> <p><img class="rich_pages wxw-img" data-ratio="0.35432230522945574" data-type="png" data-w="937" style="height: auto !important;" src="/upload/3aa95cac023f80496876d3ba9cbe4d76.png"></p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">在灰度方案落地实践的过程中,通常客户端会携带路由规则的标识,从而将请求发送到指定服务,在规则无法正常匹配的时候,由主干服务处理,对于一些核心的开关标识在配置中心统一维护;</p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;color: black;font-size: 20px;"><span style="display: none;"></span><span style="font-size: 16px;color: #222;">2、路由标识</span><span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;"><span style="font-weight: 700;color: rgb(248, 57, 41);">标识获取</span></p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">通常情况下,路由的标识是在请求头中携带的,这样比较方便统一管理,常用的传递格式如下:</p> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;color: rgb(248, 57, 41);" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(53, 53, 53);"> 版本号统一路由:routeId:2.0.0,即所有请求优先在 <code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(255, 93, 108);">2.0.0</code>分支执行; </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(53, 53, 53);"> 服务定制化路由:serverC:3.0.0,请求服务C时优先在 <code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(255, 93, 108);">3.0.0</code>分支执行; </section></li> </ul> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">在微服务的组件中获取请求头的方式很多,比如Gateway网关中的路由过滤器,或者服务中的拦截器,都可以获取请求的相关参数信息,从而执行路由规则;</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;"><span style="font-weight: 700;color: rgb(248, 57, 41);">标识管理</span></p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">自定义路由规则需要客户端标识,虽然获取请求中的标识并不复杂,但是将标识传递到路由规则中就涉及到上下文参数管理:</p> <p><img class="rich_pages wxw-img" data-ratio="0.3062966915688367" data-type="png" data-w="937" style="height: auto !important;" src="/upload/8a785e7b3c346118bfcf4f1c046f1d36.png"></p> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;color: rgb(248, 57, 41);" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(53, 53, 53);"> 写阶段:在过滤或拦截中获取路由标识,写入上下文容器; </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(53, 53, 53);"> 读阶段:路由时从容器中读取标识,基于配置信息执行规则; </section></li> </ul> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">请求从进入网关开始,在服务间通信时会涉及负载均衡的策略,在过滤或拦截器中将标识写到上下文容器,执行路由规则需要读取上下文容器,如果标识不存在则默认选择主干服务执行请求;</p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;color: black;font-size: 20px;"><span style="display: none;"></span><span style="font-size: 16px;color: #222;">3、服务选中</span><span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">微服务之间通信时,选中一个服务执行请求的逻辑比较复杂,尤其在灰度模式下涉及到对路由规则的改造,即策略指定的服务优先被选中;</p> <p><img class="rich_pages wxw-img" data-ratio="0.37139807897545357" data-type="png" data-w="937" style="height: auto !important;" src="/upload/11fecc2c64c8c192b0abd6e21dc3dd60.png"></p> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;color: rgb(248, 57, 41);" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(53, 53, 53);"> 1、从注册中心查询相应服务的可用列表; </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(53, 53, 53);"> 2、基于路由规则,匹配符合请求标识的服务; </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(53, 53, 53);"> 3、对筛选的结果列表执行负载均衡,选中服务; </section></li> </ul> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">在整个路由机制中,会涉及到匹配规则自定义改造,从常规的手段来看,将版本的分支号加载到服务的元数据信息中,再结合服务名称或者IP地址,来实现对服务列表的多维度过滤,可以支撑大部分轻量级灰度策略的实现。</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;border-radius: 16px;overflow: hidden;"></figure> </section>
作者:微信小助手
<section class="channels_iframe_wrp"> <br> </section> <p style="text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;margin: 1.5em 8px;letter-spacing: 0.1em;margin-block: 10px;white-space: normal;color: rgb(63, 63, 63);font-size: 14px;"> 前几天在B站刷到AI孙燕姿唱的《黑色毛衣》,让我听傻了,还原度还能这么高的。于是就研究了一下,做了几段居然效果还行,可以在这里听《爱得太迟》。</p> <section class="channels_iframe_wrp"> <mp-common-videosnap class="js_uneditable custom_select_card channels_iframe videosnap_video_iframe" data-pluginname="mpvideosnap" data-weui-theme="light" data-url="https://findermp.video.qq.com/251/20350/stodownload?encfilekey=oibeqyX228riaCwo9STVsGLPj9UYCicgttvRGb0ibgTJM0xsIXiboNlEw4tp7vswo7LUJoWbKeLrPFtGLH1iatJibvQdRwO2l66rDp23KPDhPjdWhbqDOfQuOsGTbeQbnNQmFKDcGSTEpkrtos&adaptivelytrans=0&bizid=1023&dotrans=0&hy=SH&idx=1&m=48a44e59403c123265de83de1d117903&token=x5Y29zUxcibA1rol3wcIlVckUJCOulyicTFsyyM4jEkHWKGMSB9MYiaDPuSIZygTIzibS0kTZaf3LQc" data-headimgurl="http://wx.qlogo.cn/finderhead/EiaeLNTCu3EW3KLfetdWEbxibyLQIupbCeOmlKsfPL0LA/0" data-username="v2_060000231003b20faec8c7eb8911c6d4cf00e432b077bc294083c45937fd15ae09793232d264@finder" data-nickname="歸藏2079" data-desc="AI孙燕姿《爱的太迟》,这个效果好太多了。 测试了一下粤语的效果。" data-nonceid="17050541699999615895" data-type="video" data-mediatype="undefined" data-authiconurl="" data-from="new" data-width="1920" data-height="1080" data-id="export/UzFfAgtgekIEAQAAAAAAKesL6yDIdgAAAAstQy6ubaLX4KHWvLEZgBPE2qMsbGlnZJiAzNPgMIsXc2OFy9A4nu5yV9mXtxss" data-isdisabled="0" data-errortips=""></mp-common-videosnap> </section> <p style="text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;margin: 1.5em 8px;letter-spacing: 0.1em;margin-block: 10px;white-space: normal;color: rgb(63, 63, 63);font-size: 14px;"> 简单解释一下,这个项目分为两个部分,模型的使用和模型的训练,模型使用的话对电脑的要求不是很高基本上差不多点的N卡都可以,模型的训练其实对显卡要求还挺高的小于6G会有各种各样的问题,当然也能炼,不过太麻烦了不建议。 </p> <p style="text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;margin: 1.5em 8px;letter-spacing: 0.1em;margin-block: 10px;white-space: normal;color: rgb(63, 63, 63);font-size: 14px;"> 主要使用的是So-VITS-SVC 4.0这个项目,github地址是:<span style="border-bottom: 0.05em solid rgba(252, 121, 48, 0.4);border-top-color: rgba(252, 121, 48, 0.4);border-right-color: rgba(252, 121, 48, 0.4);border-left-color: rgba(252, 121, 48, 0.4);">https://github.com/svc-develop-team/so-vits-svc</span> </p> <p style="text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;margin: 1.5em 8px;letter-spacing: 0.1em;margin-block: 10px;white-space: normal;color: rgb(63, 63, 63);font-size: 14px;"> 我这里会使用整合包来推理(使用模型)和训练,目前B站有两个作者做的整合包分别是羽毛布団的和领航员未鸟的我把视频地址都放在下面。希望各位去视频给个三连毕竟用了人家的劳动成果。 </p> <p style="text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;margin: 1.5em 8px;letter-spacing: 0.1em;margin-block: 10px;white-space: normal;color: rgb(63, 63, 63);font-size: 14px;"> 两位的视频教程也很好,我这边主要会更详细一些,会补充一些两位没说到但是有坑的地方。这次课程我使用的主要是羽毛布団的整合包,我把所有需要下载的都打包了。 </p> <p style="text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;margin: 1.5em 8px;letter-spacing: 0.1em;margin-block: 10px;white-space: normal;color: rgb(63, 63, 63);font-size: 14px;"> 羽毛布団:<span style="border-bottom: 0.05em solid rgba(252, 121, 48, 0.4);border-top-color: rgba(252, 121, 48, 0.4);border-right-color: rgba(252, 121, 48, 0.4);border-left-color: rgba(252, 121, 48, 0.4);">https://www.bilibili.com/video/BV1H24y187Ko/?spm_id_from=333.1007.top_right_bar_window_history.content.click&vd_source=e99f85042059f2864f5cca20d71575f0</span> </p> <p style="text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;margin: 1.5em 8px;letter-spacing: 0.1em;margin-block: 10px;white-space: normal;color: rgb(63, 63, 63);font-size: 14px;"> 领航员未鸟:<span style="border-bottom: 0.05em solid rgba(252, 121, 48, 0.4);border-top-color: rgba(252, 121, 48, 0.4);border-right-color: rgba(252, 121, 48, 0.4);border-left-color: rgba(252, 121, 48, 0.4);">https://www.bilibili.com/video/BV1Eb411f7gX/?spm_id_from=333.1007.top_right_bar_window_history.content.click&vd_source=e99f85042059f2864f5cca20d71575f0</span> </p> <p style="text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;margin: 1.5em 8px;letter-spacing: 0.1em;margin-block: 10px;white-space: normal;color: rgb(63, 63, 63);font-size: 14px;"> 所需软件和模型下载(百度云):<span style="border-bottom: 0.05em solid rgba(252, 121, 48, 0.4);border-top-color: rgba(252, 121, 48, 0.4);border-right-color: rgba(252, 121, 48, 0.4);border-left-color: rgba(252, 121, 48, 0.4);"><span style="color: rgb(63, 63, 63);font-size: 14px;letter-spacing: 1.4px;text-decoration: none solid rgb(63, 63, 63);">https://pan.baidu.com/s/12u_LDyb5KSOfvjJ9LVwCIQ?pwd=g8n4</span></span></p> <h2 style="background: rgb(252, 121, 48);color: rgb(255, 255, 255);font-size: 17px;text-align: center;line-height: 1.75;font-weight: bold;display: table;margin: 4em auto 2em;padding-right: 0.2em;padding-left: 0.2em;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;">模型使用 </h2> <p style="text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;margin: 1.5em 8px;letter-spacing: 0.1em;margin-block: 10px;white-space: normal;color: rgb(63, 63, 63);font-size: 14px;"> 首先是模型使用的部分,如果你没有兴趣训练自己的模型只想使用别人训练好的模型尝鲜的话只看这部分就可以了,这部分主要分为三个本部分原始声音的处理、推理过程以及最后的音轨合并。 </p> <h3 style="font-size: 17px;font-weight: bold;margin-top: 2em;margin-right: 8px;margin-bottom: 0.75em;padding-left: 8px;border-left: 3px solid rgb(252, 121, 48);font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;">原始声音处理 </h3> <p style="text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;margin: 1.5em 8px;letter-spacing: 0.1em;margin-block: 10px;white-space: normal;color: rgb(63, 63, 63);font-size: 14px;"> 要使用模型进行推理的话你首先需要一段已经演唱好的声音垫进去,然后使用模型把原来的音色换成你模型训练好的音色(类似AI画图的img2img垫图)。所以我们需要先对你垫进去的声音进行处理,去掉原始音乐里面的混响和乐器声音,只留下人物的干声这样效果会好一些。 </p> <p style="text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;margin: 1.5em 8px;letter-spacing: 0.1em;margin-block: 10px;white-space: normal;color: rgb(63, 63, 63);font-size: 14px;"> 我们会使用UVR_v5.5.0这个软件来处理声音通过两段处理保留人物的干声。 </p> <p style="text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;margin: 1.5em 8px;letter-spacing: 0.1em;margin-block: 10px;white-space: normal;color: rgb(63, 63, 63);font-size: 14px;"> 首先是安装,直接双击UVR_v5.5.0_setup.exe一直下一步就行,安装完成后我们需要给UVR增加一个模型解压UVR5模型文件将里面的两个文件夹粘贴到安装目录下的Ultimate Vocal Remover\models就行。 </p> <p style="text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;margin: 1.5em 8px;letter-spacing: 0.1em;margin-block: 10px;white-space: normal;color: rgb(63, 63, 63);font-size: 14px;"> 在处理之前你需要把你声音的格式转换成WAV格式,因为So-VITS-SVC 4.0只认WAV格式的音频文件,现在处理了后面会省事点。可以用这个工具处理:<span style="border-bottom: 0.05em solid rgba(252, 121, 48, 0.4);border-top-color: rgba(252, 121, 48, 0.4);border-right-color: rgba(252, 121, 48, 0.4);border-left-color: rgba(252, 121, 48, 0.4);">https://www.aconvert.com/cn/audio/mp4-to-wav/</span> </p> <p style="text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;margin: 1.5em 8px;letter-spacing: 0.1em;margin-block: 10px;white-space: normal;color: rgb(63, 63, 63);font-size: 14px;"> 处理完音频文件后我们就要开始利用UVR去掉背景音了,一共需要过两次,每次的设置都是不同的,这样能最大限度的保证不需要的声音能被去除干净。 </p> <p style="text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;margin: 1.5em 8px;letter-spacing: 0.1em;margin-block: 10px;white-space: normal;color: rgb(63, 63, 63);font-size: 14px;"> 在Select Input选择你需要处理的音频文件,处理完成后你可以在Output的文件夹下面找到处理完成的文件,后缀有(Vocals)就是人声,后缀为(Instrumental)就是伴奏,伴奏先不要删,我们后面合成的时候还需要。 </p> <p style="text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;margin: 1.5em 8px;letter-spacing: 0.1em;margin-block: 10px;white-space: normal;color: rgb(63, 63, 63);font-size: 14px;"> 下图为第一次处理UVR的参数: </p> <figure> <img class="rich_pages wxw-img" data-ratio="1.0740740740740742" src="/upload/95b7c44830f4a02b52ea1860db2ed97c.png" data-type="other" data-w="1080" style="border-radius: 8px;" width="100%"> <figcaption style="color: #37352FA6;text-align: center;font-size: 14px;"></figcaption> </figure> <p style="text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;margin: 1.5em 8px;letter-spacing: 0.1em;margin-block: 10px;white-space: normal;color: rgb(63, 63, 63);font-size: 14px;"> 完成第一次处理后我们再调整参数进行第二次处理,下面是第二次处理需要的参数设置: </p> <figure> <img class="rich_pages wxw-img" data-ratio="1.0740740740740742" src="/upload/170248f5cc7fd27f59600e71a97b95c8.png" data-type="other" data-w="1080" style="border-radius: 8px;" width="100%"> <figcaption style="color: #37352FA6;text-align: center;font-size: 14px;"></figcaption> </figure> <p style="text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;margin: 1.5em 8px;letter-spacing: 0.1em;margin-block: 10px;white-space: normal;color: rgb(63, 63, 63);font-size: 14px;"> 接下来我们就要运行整合包的Web UI来推理声音了,如果你用的其他人的模型的话你需要先把模型文件放进整合包对应的文件夹下面: </p> <p style="text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;margin: 1.5em 8px;letter-spacing: 0.1em;margin-block: 10px;white-space: normal;color: rgb(63, 63, 63);font-size: 14px;"> 首先是GAN模型和Kmeans模型就是模型文件夹下面后缀为pth和pt的两个文件放到整合包的\logs\44k文件夹下。 </p> <p style="text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;margin: 1.5em 8px;letter-spacing: 0.1em;margin-block: 10px;white-space: normal;color: rgb(63, 63, 63);font-size: 14px;"> 之后是配置文件,就是你下载下来的模型文件里那个叫config.json的json文件,放到整合包的\configs文件夹下面。 </p> <p style="text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;margin: 1.5em 8px;letter-spacing: 0.1em;margin-block: 10px;white-space: normal;color: rgb(63, 63, 63);font-size: 14px;"> 接下来我们就可以运行整合包的Web UI了,打开整合包根目录下的【<span style="font-weight:600;" data-token-index="1">启动webui.bat】</span>这个文件他会自动运行并打开Web UI的网页,经常玩Stable Diffusion的朋友肯定对这个操作不陌生。 </p> <p style="text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;margin: 1.5em 8px;letter-spacing: 0.1em;margin-block: 10px;white-space: normal;color: rgb(63, 63, 63);font-size: 14px;"> 下面就是Web UI的界面我们使用模型的时候主要用的是推理这个功能。 </p> <figure> <img class="rich_pages wxw-img" data-ratio="0.7648148148148148" src="/upload/80cb6880460b56a451eea3be471c0ca6.png" data-type="other" data-w="1080" style="border-radius: 8px;" width="100%"> <figcaption style="color: #37352FA6;text-align: center;font-size: 14px;"></figcaption> </figure> <p style="text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;margin: 1.5em 8px;letter-spacing: 0.1em;margin-block: 10px;white-space: normal;color: rgb(63, 63, 63);font-size: 14px;"> 之后就是选择我们的模型,如果你刚才已经把模型放到合适的位置的话你现在应该能在下图的两个位置选择到你的模型和配置文件,如果有报错会在输出信息的位置显示。 </p> <figure> <img class="rich_pages wxw-img" data-ratio="0.43796296296296294" src="/upload/d5088dc3159e6bb9d6562e21775bde4e.png" data-type="other" data-w="1080" style="border-radius: 8px;" width="100%"> <figcaption style="color: #37352FA6;text-align: center;font-size: 14px;"></figcaption> </figure> <p style="text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;margin: 1.5em 8px;letter-spacing: 0.1em;margin-block: 10px;white-space: normal;color: rgb(63, 63, 63);font-size: 14px;"> 选择完模型之后我们需要点击加载模型,等待一段时间Loading之后模型会加载完成。Output Message这里会输出加载的结果。 </p> <figure> <img class="rich_pages wxw-img" data-ratio="0.4888888888888889" src="/upload/3b1ba8af7b07e3d9f416cc1481ad7015.png" data-type="other" data-w="1080" style="border-radius: 8px;" width="100%"> <figcaption style="color: #37352FA6;text-align: center;font-size: 14px;"></figcaption> </figure> <p style="text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;margin: 1.5em 8px;letter-spacing: 0.1em;margin-block: 10px;white-space: normal;color: rgb(63, 63, 63);font-size: 14px;"> 之后就是上传我们处理好的需要垫的音频文件了,把文件拖动到红框位置就行。 </p> <figure> <img class="rich_pages wxw-img" data-ratio="0.5212962962962963" src="/upload/2840ffc203127b586b75fb9c24594453.png" data-type="other" data-w="1080" style="border-radius: 8px;" width="100%"> <figcaption style="color: #37352FA6;text-align: center;font-size: 14px;"></figcaption> </figure> <p style="text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;margin: 1.5em 8px;letter-spacing: 0.1em;margin-block: 10px;white-space: normal;color: rgb(63, 63, 63);font-size: 14px;"> 接下来是两个比较重要的选项【聚类f0】会让输出效果更好,但是如果你的文件是歌声的话不要勾选这个选项,不然会疯狂跑调。【F0均值滤波】主要解决哑音问题,如果你输出的内容有比较明显的哑音的话可以勾选尝试一下,这个选项歌声可以使用。 </p> <p style="text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;margin: 1.5em 8px;letter-spacing: 0.1em;margin-block: 10px;white-space: normal;color: rgb(63, 63, 63);font-size: 14px;"> 除了这两个选项之外的其他选项不建议动。除非你理解它是什么意思。 </p> <figure> <img class="rich_pages wxw-img" data-ratio="0.5342592592592592" src="/upload/4f0a86ff2ae713d08d16beb4c86fff83.png" data-type="other" data-w="1080" style="border-radius: 8px;" width="100%"> <figcaption style="color: #37352FA6;text-align: center;font-size: 14px;"></figcaption> </figure> <p style="text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;margin: 1.5em 8px;letter-spacing: 0.1em;margin-block: 10px;white-space: normal;color: rgb(63, 63, 63);font-size: 14px;"> 设置好之后我们点击【音频转换】按钮之后经过一段时间的运算,就可以生成对应的音乐了。 </p> <figure> <img class="rich_pages wxw-img" data-ratio="0.5805555555555556" src="/upload/cc1e6e93b3b135539c4b0401ef355154.png" data-type="other" data-w="1080" style="border-radius: 8px;" width="100%"> <figcaption style="color: #37352FA6;text-align: center;font-size: 14px;"></figcaption> </figure> <p style="text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;margin: 1.5em 8px;letter-spacing: 0.1em;margin-block: 10px;white-space: normal;color: rgb(63, 63, 63);font-size: 14px;"> 【output audio】的位置就是生成的音频了可以试听,如果觉得OK的话可以,点击右边三个点弹出的下载按钮下载。 </p> <figure> <img class="rich_pages wxw-img" data-ratio="0.7324074074074074" src="/upload/fdc83795fb711b91addc091ed06f0bf3.png" data-type="other" data-w="1080" style="border-radius: 8px;" width="100%"> <figcaption style="color: #37352FA6;text-align: center;font-size: 14px;"></figcaption> </figure> <p style="text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;margin: 1.5em 8px;letter-spacing: 0.1em;margin-block: 10px;white-space: normal;color: rgb(63, 63, 63);font-size: 14px;"> 我们现在生成的是一段只有人声的干声,这时候我们刚才剥离出来的伴奏就有用了,把两段音频合成就行,我用的剪映,直接把两段音轨拖进去导出就行,也可以加张图片变成视频。 </p> <figure> <img class="rich_pages wxw-img" data-ratio="0.5472222222222223" src="/upload/d423d533ab0805c20787dac3230494e2.png" data-type="other" data-w="1080" style="border-radius: 8px;" width="100%"> <figcaption style="color: #37352FA6;text-align: center;font-size: 14px;"></figcaption> </figure> <p style="text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;margin: 1.5em 8px;letter-spacing: 0.1em;margin-block: 10px;white-space: normal;color: rgb(63, 63, 63);font-size: 14px;"> 好了模型的使用部分到这里就结束了,理论上你现在如果有孙燕姿的模型的话已经可以生产AI音乐了。垫的音频文件也有一些要求,首先肯定是人声要清晰,伴奏最好少点去的也干净同时效果也会更好。 </p> <p style="text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;margin: 1.5em 8px;letter-spacing: 0.1em;margin-block: 10px;white-space: normal;color: rgb(63, 63, 63);font-size: 14px;"> AI孙燕姿我用的是B站<span style="font-weight:600;" data-token-index="1">Ozzy23</span>的模型他的这个模型效果非常好各位可以去他视频下面的简介下载,不要忘了三连。 </p> <p style="text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;margin: 1.5em 8px;letter-spacing: 0.1em;margin-block: 10px;white-space: normal;color: rgb(63, 63, 63);font-size: 14px;"> <span style="border-bottom: 0.05em solid rgba(252, 121, 48, 0.4);border-top-color: rgba(252, 121, 48, 0.4);border-right-color: rgba(252, 121, 48, 0.4);border-left-color: rgba(252, 121, 48, 0.4);">https://www.bilibili.com/video/BV1kk4y1Y7vp/?spm_id_from=333.999.0.0&vd_source=e99f85042059f2864f5cca20d71575f0</span> </p> <p style="text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;margin: 1.5em 8px;letter-spacing: 0.1em;margin-block: 10px;white-space: normal;color: rgb(63, 63, 63);font-size: 14px;"> 以上就是AI歌手的第一部分内容了,模型的训练部分内容会在稍晚的时候放出,感谢各位,看在藏师傅生病肝教程的份上希望可以多多支持。 </p> <p style="text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;margin: 1.5em 8px;letter-spacing: 0.1em;margin-block: 10px;white-space: normal;color: rgb(63, 63, 63);font-size: 14px;"> </p> <p style="text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;margin: 1.5em 8px;letter-spacing: 0.1em;margin-block: 10px;white-space: normal;color: rgb(63, 63, 63);font-size: 14px;"><br></p> <p><br></p> <p style="display: none;"> <mp-style-type data-value="3"></mp-style-type></p>