<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>b1ngz的笔记本</title>
    <link>https://wechat2rss.xlab.app/feed/985deae60a431c56b6d8b4a8f7e5623a6b7dd948.xml</link>
    <description>Think, Try And Write About Security And Coding.&#xA;(wechat feed made by @ttttmr https://wechat2rss.xlab.app)</description>
    <managingEditor> (b1ngz的笔记本)</managingEditor>
    <image>
      <url>https://wx.qlogo.cn/mmhead/Q3auHgzwzM43v5FjaoicIoicaudYZCBR13cLWhRf09icvNThgeNWQo80w/0</url>
      <title>b1ngz的笔记本</title>
      <link>https://wechat2rss.xlab.app/feed/985deae60a431c56b6d8b4a8f7e5623a6b7dd948.xml</link>
    </image>
    <item>
      <title>SaaS多租户自动化渗透平台-数据安全隔离实践</title>
      <link>https://mp.weixin.qq.com/s?__biz=MzkwNDE5NzUyMA==&amp;mid=2247483699&amp;idx=1&amp;sn=3d35c690bff8246d0f8e320c59108828</link>
      <description>本文分享了 SaaS 多租户自动化渗透平台在数据安全隔离方面的设计思路、代码实践步骤、以及因数据库框架默认特性导致“跨租户数据越权访问”安全问题的排查和解决过程</description>
      <content:encoded><![CDATA[<p>
原创 <span>b1ngz</span> <span>2024-09-27 17:00</span> <span style="display: inline-block;">北京</span>
</p>

<p>本文分享了 SaaS 多租户自动化渗透平台在数据安全隔离方面的设计思路、代码实践步骤、以及因数据库框架默认特性导致“跨租户数据越权访问”安全问题的排查和解决过程</p>
<p></p>



<p>
<img src="https://wechat2rss.xlab.app/img-proxy/?k=1fe5f80e&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F1JicUwKQqRQ7VeezpovtfjXuSEPEQ6n98xsofHiclXNElympFICb4S9TZUsako3CsPX1NgEpwrbhQ5cnVFrZ6K0A%2F0%3Fwx_fmt%3Djpeg"/>
</p>


<p style="margin-bottom: 8px;"><span style="font-size: 20pt;font-weight: bold;text-align: left;font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;letter-spacing: 0.034em;">0x01. 简介</span></p><hr style="border-style: solid;border-width: 1px 0 0;border-color: rgba(0,0,0,0.1);-webkit-transform-origin: 0 0;-webkit-transform: scale(1, 0.5);transform-origin: 0 0;transform: scale(1, 0.5);"/><article data-identifier-application__slash__x-doc-key="1GXn4BzwGypKODQ4"><p style="text-align: left;margin-top: 16px;margin-bottom: 8px;"><span data-type="text">在上一篇 </span><a href="https://mp.weixin.qq.com/s?__biz=MzkwNDE5NzUyMA==&amp;mid=2247483694&amp;idx=1&amp;sn=f790233f79f52fb60fcd1aefa25d4820&amp;scene=21#wechat_redirect" data-link-href-cangjie="https://mp.weixin.qq.com/s?__biz=MzkwNDE5NzUyMA==&amp;mid=2247483694&amp;idx=1&amp;sn=f790233f79f52fb60fcd1aefa25d4820&amp;scene=21#wechat_redirect" target="_blank" rel="noopener noreferrer" data-linktype="2"><span data-type="text">SaaS多租户自动化渗透平台-架构笔记</span></a><span data-type="text"> 中提到了 “客户对 SaaS 形态产品的数据安全性非常敏感”，因此实现数据安全隔离是平台的一个核心要求。同时因产品的定位是自动化渗透平台，用户为专业安全人员，使得保障平台自身的数据安全更加重要。这篇笔记介绍了在多租户架构下，实现数据安全隔离的一些思考和实践，主要内容包括</span></p><ul class="list-paddingleft-1"><li><p style="margin-bottom: 8px;line-height: 1.5em;"><span data-type="text">多租户架构数据安全隔离的要求和设计思路</span></p></li><li><p style="margin-bottom: 8px;line-height: 1.5em;"><span data-type="text">基于 Flask、SQLAlchemy、Dramatiq 框架如何实现多租户数据库安全访问</span></p></li><li><p style="margin-bottom: 8px;line-height: 1.5em;"><span data-type="text">ORM 框架特性导致出现“数据库跨租户越权”问题的排查过程和解决办法</span></p></li></ul><section style="-webkit-tap-highlight-color: transparent;margin-bottom: 16px;outline: 0px;font-family: &#34;PingFang SC&#34;, system-ui, -apple-system, &#34;system-ui&#34;, &#34;Helvetica Neue&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;visibility: visible;margin-top: 24px;"><span style="letter-spacing: 0.544px;font-size: var(--articleFontsize);">PS：🔥 团队急</span><span style="letter-spacing: 0.544px;font-size: var(--articleFontsize);">招</span><span style="letter-spacing: 0.544px;font-size: var(--articleFontsize);">后端研发，感兴趣可私信联系。另外公司正在广纳人才，可复制访问下方链接在线查看职位详情和投递简历</span><br/></section><p style="-webkit-tap-highlight-color: transparent;margin-bottom: 0px;outline: 0px;font-family: &#34;PingFang SC&#34;, system-ui, -apple-system, &#34;system-ui&#34;, &#34;Helvetica Neue&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: center;visibility: visible;"> <span style="-webkit-tap-highlight-color: transparent;outline: 0px;font-size: 18px;visibility: visible;"><strong style="-webkit-tap-highlight-color: transparent;outline: 0px;letter-spacing: 0.578px;text-align: left;color: rgb(255, 0, 0);visibility: visible;"><a href="https://app.mokahr.com/su/5wsls " target="_blank">https://app.mokahr.com/su/5wsls </a></strong></span></p><section style="margin-bottom: 8px;"><span data-type="text"><br/></span></section><h1 style="font-size: 20pt;line-height: 85%;margin-top: 26.6667px;text-align: left;margin-bottom: 16px;"><span data-type="text" style="font-weight:bold;font-size:20pt;">0x02. 要求和思路</span></h1><hr style="border-style: solid;border-width: 1px 0 0;border-color: rgba(0,0,0,0.1);-webkit-transform-origin: 0 0;-webkit-transform: scale(1, 0.5);transform-origin: 0 0;transform: scale(1, 0.5);"/><section style="text-align: left;margin-top: 16px;margin-bottom: 8px;"><span data-type="text">在多租户架构下，不同客户的访问和操作均对应同一套代码和服务，</span><span data-type="text" style="font-weight:bold;">如何防止一个用户越权访问到其他租户的数据</span><span data-type="text">，是一个非常关键和基础的安全问题。这里首先想到的方案是，每个租户分配一个独立的数据库，有不同的账号密码，并限制访问权限。而从研发安全的视角，需要尽量避免在写业务代码时，手动处理选择和访问数据库资源的操作，即在底层进行统一的封装和屏蔽，实现根据当前用户所属的租户自动选择对应的数据库。而这也依赖用户所属租户的信息无法被篡改和伪造，即需要保证身份认证的安全性</span></section><section style="text-align: left;margin-bottom: 8px;"><span data-type="text">梳理一下，有几个要点</span></section><ol class="list-paddingleft-1"><li><section style="margin-bottom: 8px;"><span data-type="text">获取当前登陆用户所属租户信息的代码逻辑是安全的</span></section></li><li><section style="margin-bottom: 8px;"><span data-type="text">业务代码只关注功能逻辑，对数据库的选择无感知</span></section></li><li><section style="margin-bottom: 24px;"><span data-type="text">不同租户对应不同数据库、不同账号密码，无法相互访问</span></section></li></ol><h1 style="font-size: 20pt;line-height: 85%;margin-top: 26.6667px;text-align: left;margin-bottom: 16px;"><span data-type="text" style="font-weight:bold;font-size:20pt;">0x03. 代码实践</span></h1><hr style="border-style: solid;border-width: 1px 0 0;border-color: rgba(0,0,0,0.1);-webkit-transform-origin: 0 0;-webkit-transform: scale(1, 0.5);transform-origin: 0 0;transform: scale(1, 0.5);"/><p style="text-align: left;margin-top: 16px;margin-bottom: 8px;"><span data-type="text">平台使用的技术栈为：Web 框架 Flask 、数据库框架 SQLAlchemy、异步任务框架 Dramatiq</span></p><section style="text-align: left;margin-bottom: 16px;"><span data-type="text">实现过程包括</span></section><ol class="list-paddingleft-1"><li style="font-size: 18px;"><section style="margin-bottom: 16px;"><span style="font-weight: bold;font-size: 18px;">获取当前用户所属租户信息</span></section></li></ol><p style="text-align: left;margin-bottom: 8px;"><span data-type="text">这里使用 JSON Web Token (JWT) 的方式来保存用户身份和所属租户信息。对于 JWT 的安全，需要确保进行 </span><span data-type="text" style="background-color:rgb(252, 252, 252);">signature</span><span data-type="text"> 的验证（第三方库通常默认开启），以及使用的 secret key 复杂度足够强。另外为了避免共用 secret key 泄露后相互影响，这里为每个租户生成不同了 secret key。代码示例如下</span></p><pre><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li></ul><pre class="code-snippet__js" data-lang="ini"><code><span class="code-snippet_outer"><span class="code-snippet__attr">verified_info</span> = jwt.decode(jwt_token, jwt_secret)</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">enterprise_id</span> = verified_info.get(<span class="code-snippet__string">&#34;enterprise_id&#34;</span>)</span></code></pre></section><p style="margin-bottom: 24px;"><span data-type="text" style="font-size: var(--articleFontsize);letter-spacing: 0.034em;text-align: left;font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;">JWT 安全部分详细可参考 </span><span data-type="text" style="font-size: var(--articleFontsize);letter-spacing: 0.034em;text-align: left;font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"><a href="https://portswigger.net/web-security/jwt" target="_blank">https://portswigger.net/web-security/jwt</a></span></p></pre><ol start="2" class="list-paddingleft-1"><li style="font-size: 18px;"><section style="margin-bottom: 16px;"><span style="font-weight: bold;font-size: 18px;">在当前上下文设置所属租户信息</span></section></li></ol><p style="text-align: left;margin-bottom: 8px;"><span data-type="text">在 Flask 中提供了 Application Context 来实现在一次请求、CLI 命令等需要在特定执行范围内，管理和共享数据的能力。使用者可在当前上下文环境，通过 </span><code data-type="inlineCode">g</code><span data-type="text"> proxy 变量来设置、访问、修改数据。详细可参考</span></p><ul class="list-paddingleft-1" style="list-style-type: disc;"><li><p style="margin-bottom: 8px;"><span data-type="text"><a href="https://flask.palletsprojects.com/en/3.0.x/appcontext/" target="_blank">https://flask.palletsprojects.com/en/3.0.x/appcontext/</a></span></p></li><li><p style="margin-bottom: 8px;"><span data-type="text">flask.g </span><span data-type="text"><a href="https://flask.palletsprojects.com/en/3.0.x/api/#flask.g" target="_blank">https://flask.palletsprojects.com/en/3.0.x/api/#flask.g</a></span><span data-type="text"></span></p></li></ul><p style="text-align: left;margin-top: 24px;margin-bottom: 24px;"><span data-type="text" style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;">代码实现方面，需要区分不同的业务场景。一是用户使用平台访问 Web 接口，Flask 会在处理请求前后，自动 push 和 pop application context。我们只需要在用户成功登录后，通过</span><code data-type="inlineCode" style="font-size: var(--articleFontsize);letter-spacing: 0.034em;">g</code><span data-type="text" style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;">变量设置租户的信息，示例代码如下</span><br/></p><pre><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="javascript"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">from</span> flask <span class="code-snippet__keyword">import</span> g</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">g.enterprise_id = <span class="code-snippet__string">&#34;tenant-A&#34;</span></span></code></pre></section><section style="margin-bottom: 8px;margin-top: 24px;"><span style="text-align: left;font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;">另一个业务场景是执行租户相关的异步任务。此时我们需要</span><code data-syntax="python" data-theme="default"></code></section></pre><ol class="list-paddingleft-1"><li><p style="margin-bottom: 8px;"><span data-type="text">在执行任务的前后 push 和 pop application context</span></p></li><li><p style="margin-bottom: 8px;"><span data-type="text">发送任务时，自动在参数中添加所属租户信息</span></p></li><li><p style="margin-bottom: 8px;"><span data-type="text">执行任务前后，从参数中获取租户信息，通过 </span><code data-type="inlineCode">g </code><span data-type="text">变量设置/清除租户信息</span></p></li></ol><section style="text-align: left;margin-bottom: 8px;margin-top: 16px;"><span data-type="text">在 Dramatiq 框架中，我们可通过编写自定义 Middleware，在对应 hooks 函数中实现以上逻辑，详细参考 </span><span data-type="text"><a href="https://dramatiq.io/reference.html#middleware" target="_blank">https://dramatiq.io/reference.html#middleware</a></span></section><p style="text-align: left;margin-bottom: 8px;"><span data-type="text">示例代码如下，需求 1 对应 AppContextMiddleware，需求 2，3 对应 EnterpriseMiddleware</span></p><pre><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="python"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">from</span> threading <span class="code-snippet__keyword">import</span> local</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">from</span> dramatiq <span class="code-snippet__keyword">import</span> Message, Middleware</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">from</span> flask <span class="code-snippet__keyword">import</span> g</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">class</span> <span class="code-snippet__title">AppContextMiddleware</span><span class="code-snippet__params">(Middleware)</span>:</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__comment"># 每个线程有自己独立的 context</span></span></code><code><span class="code-snippet_outer">    STATE = local()</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">def</span> <span class="code-snippet__title">__init__</span><span class="code-snippet__params">(self, app)</span>:</span></span></code><code><span class="code-snippet_outer">        self.app = app</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">def</span> <span class="code-snippet__title">before_process_message</span><span class="code-snippet__params">(self, broker, message)</span>:</span></span></code><code><span class="code-snippet_outer">        context: AppContext = self.app.app_context()</span></code><code><span class="code-snippet_outer">        context.push()</span></code><code><span class="code-snippet_outer">        self.STATE.context = context</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">def</span> <span class="code-snippet__title">after_process_message</span><span class="code-snippet__params">(self, broker, message, *, result=None, exception=None)</span>:</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">try</span>:</span></code><code><span class="code-snippet_outer">            context = self.STATE.context</span></code><code><span class="code-snippet_outer">            context.pop(exception)</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">del</span> self.STATE.context</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">except</span> AttributeError:</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">pass</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    after_skip_message = after_process_message</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">class</span> <span class="code-snippet__title">EnterpriseMiddleware</span><span class="code-snippet__params">(Middleware)</span>:</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">def</span> <span class="code-snippet__title">before_enqueue</span><span class="code-snippet__params">(self, broker, message: Message, delay)</span>:</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__comment"># 发送任务时自动设置  enterprise_id</span></span></code><code><span class="code-snippet_outer">        message.options.setdefault(<span class="code-snippet__string">&#34;enterprise_id&#34;</span>, g.enterprise_id)</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">def</span> <span class="code-snippet__title">before_process_message</span><span class="code-snippet__params">(self, broker, message)</span>:</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> enterprise_id := message.options.get(<span class="code-snippet__string">&#34;enterprise_id&#34;</span>, <span class="code-snippet__keyword">None</span>):</span></code><code><span class="code-snippet_outer">            g.enterprise_id = enterprise_id</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">def</span> <span class="code-snippet__title">after_process_message</span><span class="code-snippet__params">(self, broker, message, *, result=None, exception=None)</span>:</span></span></code><code><span class="code-snippet_outer">        g.pop(<span class="code-snippet__string">&#34;enterprise_id&#34;</span>, <span class="code-snippet__keyword">None</span>)</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    after_skip_message = after_process_message</span></code></pre></section><p style="margin-bottom: 8px;"><code data-syntax="python" data-theme="default"></code></p></pre><ol start="3" class="list-paddingleft-1"><li style="font-size: 18px;"><section style="margin-bottom: 16px;"><span style="font-weight: bold;font-size: 18px;">数据访问操作时，根据当前所属租户选择对应数据库</span></section></li></ol><p style="text-align: left;margin-bottom: 8px;"><span data-type="text">在 SQLAlchemy 中，会使用 Session 来进行 ORM 相关操作，我们可以通过重写 Session 的 </span><code data-type="inlineCode">get_bind </code><span data-type="text">方法来实现根据第一步中的租户信息 </span><code data-type="inlineCode">g.enterprise_id </code><span data-type="text">来动态选择对应数据库连接（通常为 Engine 实例）</span></p><p style="text-align: left;margin-bottom: 8px;"><span data-type="text">代码示例如下</span></p><pre><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="python"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">from</span> flask_sqlalchemy.session <span class="code-snippet__keyword">import</span> Session</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">from</span> flask <span class="code-snippet__keyword">import</span> g</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__class"><span class="code-snippet__keyword">class</span> <span class="code-snippet__title">DynamicSession</span><span class="code-snippet__params">(Session)</span>:</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">def</span> <span class="code-snippet__title">get_bind</span><span class="code-snippet__params">(</span></span></span></code><code><span class="code-snippet_outer">        self,</span></code><code><span class="code-snippet_outer">        mapper: t.Any | None = None,</span></code><code><span class="code-snippet_outer">        clause: t.Any | None = None,</span></code><code><span class="code-snippet_outer">        bind: sa.engine.Engine | sa.engine.Connection | None = None,</span></code><code><span class="code-snippet_outer">        **kwargs: t.Any,</span></code><code><span class="code-snippet_outer"><span class="code-snippet_outer">    )</span> -&gt; sa.engine.Engine | sa.engine.Connection:</span></code><code><span class="code-snippet_outer">        found_bind = <span class="code-snippet__keyword">None</span></span></code><code><span class="code-snippet_outer">  </span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> bind_key := g.get(<span class="code-snippet__string">&#34;enterprise_id&#34;</span>, <span class="code-snippet__string">&#34;&#34;</span>):</span></code><code><span class="code-snippet_outer">            found_bind = self._db.engines.get(bind_key)</span></code><code><span class="code-snippet_outer">        </span></code><code><span class="code-snippet_outer">        <span class="code-snippet__comment"># 其他逻辑 ...</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> <span class="code-snippet__keyword">not</span> found_bind:</span></code><code><span class="code-snippet_outer">            found_bind = super().get_bind(mapper, clause, bind, **kwargs)</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> found_bind</span></code></pre></section><p style="margin-bottom: 8px;"><code data-syntax="python" data-theme="default"></code></p></pre><p style="text-align: left;margin-bottom: 8px;"><span data-type="text">其中 </span><code data-type="inlineCode">self._db.engines </code><span data-type="text">保存了所有租户数据库的连接信息，类型为 map，key 为租户的 ID。这部分由另一个独立的线程定时同步和动态加载租户的数据库连接配置。</span></p><p style="text-align: left;margin-bottom: 8px;"><br/></p><p style="text-align: left;margin-bottom: 8px;"><span data-type="text">详细可参考</span></p><ul class="list-paddingleft-1"><li><p style="margin-bottom: 8px;"><span data-type="text">Session.get_bind </span><span data-type="text"><a href="https://docs.sqlalchemy.org/en/20/orm/session_api.html#sqlalchemy.orm.Session.get_bind" target="_blank">https://docs.sqlalchemy.org/en/20/orm/session_api.html#sqlalchemy.orm.Session.get_bind</a></span><span data-type="text"></span></p></li><li><p style="margin-bottom: 8px;"><span data-type="text">Engine </span><span data-type="text"><a href="https://docs.sqlalchemy.org/en/20/core/engines.html" target="_blank">https://docs.sqlalchemy.org/en/20/core/engines.html</a></span></p></li></ul><h1 style="font-size: 20pt;line-height: 85%;text-align: left;margin-bottom: 16px;margin-top: 32px;"><span data-type="text" style="font-weight:bold;font-size:20pt;">0x04. 安全问题</span></h1><hr style="border-style: solid;border-width: 1px 0 0;border-color: rgba(0,0,0,0.1);-webkit-transform-origin: 0 0;-webkit-transform: scale(1, 0.5);transform-origin: 0 0;transform: scale(1, 0.5);"/><p style="text-align: left;margin-top: 16px;margin-bottom: 8px;"><span data-type="text">在完成上述数据安全隔离措施后，我们仍遇到了在特定场景下 “某个租户获取到了其他租户数据” 的安全问题。</span></p><section style="text-align: left;margin-bottom: 8px;"><span data-type="text">首先介绍发生问题的业务场景“扫描任务的执行”。当用户在平台创建任务后，并不会立刻被运行，而是在“任务队列表”中插入一条数据。再由“任务调度服务”定期检查任务队列表中是否有任务，满足运行的条件后才会发送到队列运行。在多租户架构下，“任务调度服务”会依次访问所有租户的数据库进行检查，其代码示例如下</span></section><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cs"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">while</span> True:</span></code><code><span class="code-snippet_outer">    enterprise_ids = get_enterprise_ids()</span></code><code><span class="code-snippet_outer">    </span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">for</span> enterprise_id <span class="code-snippet__keyword">in</span> enterprise_ids:</span></code><code><span class="code-snippet_outer">      <span class="code-snippet__meta"># 设置 g.enterprise_id 值，用于切换数据库</span></span></code><code><span class="code-snippet_outer">      <span class="code-snippet__function">with <span class="code-snippet__title">bind_enterprise</span>(<span class="code-snippet__params">enterprise_id</span>):</span></span></code><code><span class="code-snippet_outer">        # 查询待运行的任务列表</span></code><code><span class="code-snippet_outer"><span class="code-snippet_outer">        stmt</span> = <span class="code-snippet__keyword">select</span>(TaskQueue).<span class="code-snippet__keyword">where</span>(TaskQueue.handled == <span class="code-snippet__literal">false</span>())</span></code><code><span class="code-snippet_outer">        tasks = session.scalars(stmt).all()</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__meta"># ... 运行条件检查</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__meta"># 发送任务到队列</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">for</span> task <span class="code-snippet__keyword">in</span> tasks:</span></code><code><span class="code-snippet_outer">          _send_task(task)</span></code><code><span class="code-snippet_outer">          <span class="code-snippet__meta"># 每个租户单次只发送一个任务</span></span></code><code><span class="code-snippet_outer">          <span class="code-snippet__keyword">break</span></span></code><code><span class="code-snippet_outer">    </span></code><code><span class="code-snippet_outer">    time.sleep(<span class="code-snippet__number">1</span>)</span></code></pre></section><p><code data-type="inlineCode" style="text-align: left;font-size: var(--articleFontsize);letter-spacing: 0.034em;"><br/></code></p><section style="margin-bottom: 0px;"><code data-syntax="python" data-theme="default">            </code><code data-type="inlineCode" style="text-align: left;font-size: var(--articleFontsize);letter-spacing: 0.034em;"></code><code data-type="inlineCode" style="-webkit-tap-highlight-color: transparent;outline: 0px;font-size: var(--articleFontsize);text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;letter-spacing: 0.034em;">TaskQueue</code><span data-type="text" style="-webkit-tap-highlight-color: transparent;outline: 0px;font-size: var(--articleFontsize);text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;letter-spacing: 0.034em;"> mo</span><span style="-webkit-tap-highlight-color: transparent;outline: 0px;font-size: var(--articleFontsize);text-wrap: wrap;background-color: rgb(255, 255, 255);font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;letter-spacing: 0.034em;text-align: left;">del 的定义如下</span><span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;text-align: left;"></span></section><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="objectivec"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">class</span> TaskQueue(Base):</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">id</span>: Mapped[<span class="code-snippet__keyword">int</span>] = mapped_column(</span></code><code><span class="code-snippet_outer">    BigInteger(), primary_key=True</span></code><code><span class="code-snippet_outer">  )</span></code><code><span class="code-snippet_outer">  task_id: Mapped[<span class="code-snippet__keyword">int</span>] = mapped_column(</span></code><code><span class="code-snippet_outer">    BigInteger(), <span class="code-snippet__keyword">nullable</span>=False, index=True</span></code><code><span class="code-snippet_outer">  )</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__meta"># 任务对应的全局唯一消息 UUID</span></span></code><code><span class="code-snippet_outer">  message_id: Mapped[str] = mapped_column(</span></code><code><span class="code-snippet_outer">    String(<span class="code-snippet__number">36</span>), index=True, <span class="code-snippet__keyword">nullable</span>=False</span></code><code><span class="code-snippet_outer">  )</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__meta"># 是否已处理</span></span></code><code><span class="code-snippet_outer">  handled: Mapped[<span class="code-snippet__keyword">bool</span>] = mapped_column(</span></code><code><span class="code-snippet_outer">        Boolean(), <span class="code-snippet__keyword">default</span>=False, server_default=<span class="code-snippet__literal">false</span>()</span></code><code><span class="code-snippet_outer">  )</span></code></pre></section><p style="text-align: left;"><span data-type="text"><br/></span></p><p style="text-align: left;"><span data-type="text">运行任务的代码函数</span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="python"><code><span class="code-snippet_outer"><span class="code-snippet__meta">@dramatiq.actor(queue_name=&#34;task&#34;)</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">def</span> <span class="code-snippet__title">run_flow_task</span><span class="code-snippet__params">(task_id)</span>:</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">try</span>:</span></code><code><span class="code-snippet_outer">      obj = get_task_obj_by_id(task_id)</span></code><code><span class="code-snippet_outer">      ...</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">except</span> Exception:</span></code><code><span class="code-snippet_outer">      ...</span></code></pre></section><p style="text-align: left;"><span data-type="text"><br/></span></p><p style="text-align: left;"><span data-type="text">某天监控告警发现，在租户 A 下运行任务报错，错误信息为“task_id = 121 在数据库里任务记录不存在”，其消息 ID（message_id）为 </span><code data-type="inlineCode">6d4a0abc-d277-44db-8f6a-2a90491b1dee</code><span data-type="text">。之后我们开始排查，在租户 A 对应的数据库中，最大的任务 ID 为 39，确实不存在 121 的记录。接着开始查询 “任务调度服务” 的日志，发现日志中的参数值和错误信息能对应上</span></p><p style="text-align: left;"><span data-type="text"><br/></span></p><p style="text-align: center;"><span data-type="text">任务调度服务日志</span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="perl"><code><span class="code-snippet_outer">租户A：<span class="code-snippet__keyword">send</span> message_id=<span class="code-snippet__string">&#39;xxxx&#39;</span> task_id=<span class="code-snippet__number">37</span></span></code><code><span class="code-snippet_outer">租户A：<span class="code-snippet__keyword">send</span> message_id=<span class="code-snippet__string">&#39;6d4a0abc-d277-44db-8f6a-2a90491b1dee&#39;</span> task_id=<span class="code-snippet__number">121</span></span></code><code><span class="code-snippet_outer">租户A：<span class="code-snippet__keyword">send</span> message_id=<span class="code-snippet__string">&#39;xxxx&#39;</span> task_id=<span class="code-snippet__number">39</span></span></code></pre></section><p style="text-align: left;"><span data-type="text"><br/></span></p><p style="text-align: left;"><span data-type="text">根据前后的日志判断，正确的 task_id 应该是 38。到租户 A 的 “任务队列表” 中查看，确实有 38，但 message_id 是 </span><code data-type="inlineCode">47fb72b3-64dd-460d-bc03-bccfe18fa039</code><span data-type="text">与前面任务调度器的日志对应不上</span></p><p style="text-align: left;"><span data-type="text"><br/></span></p><p style="text-align: center;"><span data-type="text">租户A-任务队列表数据</span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="go"><code><span class="code-snippet_outer">id, task_id, message_id</span></code><code><span class="code-snippet_outer"><span class="code-snippet__number">40</span>, <span class="code-snippet__number">37</span>, xxxxx     </span></code><code><span class="code-snippet_outer"><span class="code-snippet__number">41</span>, <span class="code-snippet__number">38</span>, <span class="code-snippet__number">47f</span>b72b3<span class="code-snippet__number">-64d</span>d<span class="code-snippet__number">-460d</span>-bc03-bccfe18fa039</span></code><code><span class="code-snippet_outer"><span class="code-snippet__number">42</span>, <span class="code-snippet__number">39</span>, xxxx</span></code></pre></section><p style="text-align: left;"><span data-type="text"><br/></span></p><section style="text-align: left;margin-bottom: 16px;"><span data-type="text">“任务调度服务日志” 中有一个需要注意的点是，前后 task_id 37 和 39 的两个任务是正常运行的，经过手工测试，也无法复现该问题。</span></section><section style="text-align: left;margin-bottom: 16px;"><span data-type="text">因为 message_id  为全局唯一消息 ID，根据日志查询到 </span><code data-type="inlineCode">47fb72b3-64dd-460d-bc03-bccfe18fa039</code><span data-type="text">属于租户B，其“任务队列表表”数据如下，task_id 为 </span><code data-type="inlineCode">121</code><span data-type="text"> 也能对的上</span></section><p style="text-align: left;"><span data-type="text"><br/></span></p><p style="text-align: center;"><span data-type="text">租户B-任务队列表数据</span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li></ul><pre class="code-snippet__js" data-lang="go"><code><span class="code-snippet_outer">id, task_id, message_id</span></code><code><span class="code-snippet_outer"><span class="code-snippet__number">41</span>, <span class="code-snippet__number">121</span>, <span class="code-snippet__number">47f</span>b72b3<span class="code-snippet__number">-64d</span>d<span class="code-snippet__number">-460d</span>-bc03-bccfe18fa039</span></code></pre></section><p style="text-align: left;"><span data-type="text"><br/></span></p><p style="text-align: left;margin-bottom: 16px;"><span data-type="text">上述问题的表现像是“租户A”读取到的“租户B”下的数据，出现了跨租户越权的问题。起初我们怀疑是代码实现有问题，但经过排查和讨论，并未找到原因。</span></p><p style="text-align: left;margin-bottom: 16px;"><span data-type="text">我们又继续排查任务调度日志，发现在租户A之前，调度的上一个租户恰巧是租户B的，且也找到了同 </span><code data-type="inlineCode">message_id</code><span data-type="text">和 </span><code data-type="inlineCode">task_id</code><span data-type="text">的任务发送日志（第一行和第四行）</span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="perl"><code><span class="code-snippet_outer">租户B：<span class="code-snippet__keyword">send</span> message_id=<span class="code-snippet__string">&#39;6d4a0abc-d277-44db-8f6a-2a90491b1dee&#39;</span> task_id=<span class="code-snippet__number">121</span></span></code><code><span class="code-snippet_outer">...</span></code><code><span class="code-snippet_outer">租户A：<span class="code-snippet__keyword">send</span> message_id=<span class="code-snippet__string">&#39;xxxx&#39;</span> task_id=<span class="code-snippet__number">37</span></span></code><code><span class="code-snippet_outer">租户A：<span class="code-snippet__keyword">send</span> message_id=<span class="code-snippet__string">&#39;6d4a0abc-d277-44db-8f6a-2a90491b1dee&#39;</span> task_id=<span class="code-snippet__number">121</span></span></code><code><span class="code-snippet_outer">租户A：<span class="code-snippet__keyword">send</span> message_id=<span class="code-snippet__string">&#39;xxxx&#39;</span> task_id=<span class="code-snippet__number">39</span></span></code></pre></section><p style="text-align: left;"><span data-type="text"><br/></span></p><p style="text-align: left;"><span data-type="text">再根据 “任务队列表” 的数据对比，发现这两条数据拥有相同的数据库主键值，id 均为 41</span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="go"><code><span class="code-snippet_outer">租户A</span></code><code><span class="code-snippet_outer">id, task_id, message_id</span></code><code><span class="code-snippet_outer"><span class="code-snippet__number">41</span>, <span class="code-snippet__number">38</span>, <span class="code-snippet__number">47f</span>b72b3<span class="code-snippet__number">-64d</span>d<span class="code-snippet__number">-460d</span>-bc03-bccfe18fa039</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">租户B</span></code><code><span class="code-snippet_outer">id, task_id, message_id</span></code><code><span class="code-snippet_outer"><span class="code-snippet__number">41</span>, <span class="code-snippet__number">121</span>, <span class="code-snippet__number">47f</span>b72b3<span class="code-snippet__number">-64d</span>d<span class="code-snippet__number">-460d</span>-bc03-bccfe18fa039</span></code></pre></section><section style="text-align: left;margin-bottom: 8px;margin-top: 16px;"><span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;text-align: justify;">根据上述表现，我们怀疑是业务层代码在进行数据库查询时，没有刷新已加载到内存中的数据。</span><br/><span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;text-align: justify;"></span></section><section style="margin-bottom: 16px;">经过文档的搜索，发现在 SQLAlchemy ORM 中存在一个默认特性，“同一主键 model object 只会被 load 一次，后续再次查询不会更新当前 object 的状态”，目的为了保留内存中 model 已经被修改的状态，以及避免刷新已经存在数据的成本和复杂度。官方文档中的描述原文为</section><p data-type="blockquote" style="text-align: left;"><span data-type="text" style="font-size:11pt;">Normally, ORM objects are only loaded once, and if they are matched up to the primary key in a subsequent result row, the row is not applied to the object. This is both to preserve pending, unflushed changes on the object as well as to avoid the overhead and complexity of refreshing data which is already there.</span></p><p style="text-align: left;"><span data-type="text"><br/></span></p><p style="text-align: left;"><span data-type="text">文档地址：</span><span data-type="text"><a href="https://docs.sqlalchemy.org/en/20/orm/queryguide/api.html#populate-existing" target="_blank">https://docs.sqlalchemy.org/en/20/orm/queryguide/api.html#populate-existing</a></span><span data-type="text"></span></p><p style="text-align: left;"><span data-type="text"><br/></span></p><p style="text-align: left;margin-bottom: 16px;"><span data-type="text">我们来看一个代码示例，以便更好的理解特性背后的表现，这里有一个 User model，有 id 主键和 name 两个字段</span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="properties"><code><span class="code-snippet_outer"><span class="code-snippet__meta">class User(Base)</span>:<span class="code-snippet__string"></span></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__attr">__tablename__</span> = <span class="code-snippet__string">&#34;t_user&#34;</span></span></code><code><span class="code-snippet_outer">  </span></code><code><span class="code-snippet_outer">  <span class="code-snippet__attr">id</span>: <span class="code-snippet__string">Mapped[int] = mapped_column(BigInteger(), primary_key=True)</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet_outer">  <span class="code-snippet__attr">name</span>: <span class="code-snippet__string">Mapped[str] = mapped_column(String(36), nullable=False)</span></span><p><span class="code-snippet__string"></span></p></span></code></pre></section><section style="text-align: left;margin-bottom: 8px;"><span data-type="text">查询代码如下</span></section><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="properties"><code><span class="code-snippet_outer"><span class="code-snippet__comment"># 查询 id 为 2 的 user model</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">stmt</span> = <span class="code-snippet__string">select(User).where(User.id == 2)</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">user_obj</span> = <span class="code-snippet__string">session.scalar(stmt)</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"># 此时用户名为 zhangsan</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">user_obj.name</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"># 中途有其他逻辑将其 name 属性更新为了 lisi</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"># 再次查询</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">user_obj</span> = <span class="code-snippet__string">session.scalar(stmt)</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"># 此时用户名依旧为 zhangsan</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">user_obj.name</span></span></code></pre></section><p style="text-align: left;"><span data-type="text"><br/></span></p><section style="text-align: left;margin-bottom: 8px;"><span data-type="text">代码中先后两次查询了同一个 id 的 model，可以看到，在第一次查询后，即使数据库中的 name 字段已经被修改了，后续再次查询，得到的仍然是原值。</span></section><section style="text-align: left;margin-bottom: 8px;margin-top: 16px;"><span data-type="text">结合上述特性，再回顾一下问题发生的过程</span></section><ol class="list-paddingleft-1"><li><p style="margin-bottom: 8px;margin-top: 16px;"><span data-type="text">在检查</span><span data-type="text" style="font-weight:bold;">租户B</span><span data-type="text">的待执行任务时，加载了主键为 41 的 TaskQueue model</span></p></li></ol><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="go"><section style="margin-bottom: 8px;margin-top: 8px;"><code><span class="code-snippet_outer">租户B</span></code></section><code><span class="code-snippet_outer">id, task_id, message_id</span></code><code><span class="code-snippet_outer"><span class="code-snippet__number">41</span>, <span class="code-snippet__number">121</span>, <span class="code-snippet__number">47f</span>b72b3<span class="code-snippet__number">-64d</span>d<span class="code-snippet__number">-460d</span>-bc03-bccfe18fa039</span></code></pre></section><ol start="2" class="list-paddingleft-1"><li><p style="margin-bottom: 8px;margin-top: 16px;"><span data-type="text">在后续检查</span><span data-type="text" style="font-weight:bold;">租户A</span><span data-type="text">的待执行任务时，对应数据库中也有一条主键为 41 的任务队列记录</span></p></li></ol><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="go"><code><span class="code-snippet_outer">租户A</span></code><code><span class="code-snippet_outer">id, task_id, message_id</span></code><code><span class="code-snippet_outer"><span class="code-snippet__number">41</span>, <span class="code-snippet__number">38</span>, <span class="code-snippet__number">47f</span>b72b3<span class="code-snippet__number">-64d</span>d<span class="code-snippet__number">-460d</span>-bc03-bccfe18fa039</span></code></pre></section><ol start="3" class="list-paddingleft-1"><li><p style="margin-bottom: 8px;margin-top: 16px;"><span data-type="text">因为 SQLAlchemy ORM “同一主键 model object 只会被 load 一次，后续再次查询不会更新当前 object 的状态” 的特性，会直接使用之前已加载的</span><span data-type="text" style="font-weight:bold;">租户B</span><span data-type="text">的 TaskQueue model 数据，导出发出的消息参数错误，而任务运行的上下文环境为租户A，在对应 DB 下无法找到对应数据</span></p></li></ol><p style="text-align: left;"><span data-type="text"><br/></span></p><section style="text-align: left;margin-bottom: 8px;"><span data-type="text">问题可总结为：任务调度服务在检查租户下待运行任务的过程中切换了数据库，在不同数据库下加载了同一 model 相同主键的 object，而因 ORM 框架默认特性，后续的查询不会刷新内存中的 object，导致数据不正确</span></section><p style="text-align: left;margin-bottom: 8px;margin-top: 16px;"><span data-type="text">针对该问题，可选的解决办法有</span></p><ol class="list-paddingleft-1"><li><p style="margin-bottom: 8px;margin-top: 16px;"><span data-type="text">在发送完任务后，使用</span><code data-type="inlineCode">session.expire()</code><span data-type="text">将内存中的 model object 设置为 expire，下次查询时会重新加载</span></p></li></ol><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li></ul><pre class="code-snippet__js" data-lang="css"><section style="margin-bottom: 8px;"><code><span class="code-snippet_outer">_<span class="code-snippet__selector-tag">send_task</span>(<span class="code-snippet__selector-tag">task</span>)</span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">session</span><span class="code-snippet__selector-class">.expire</span>(<span class="code-snippet__selector-tag">task</span>)</span></code></section></pre></section><section style="text-align: left;margin-bottom: 8px;"><span data-type="text">参考 </span><span data-type="text"><a href="https://docs.sqlalchemy.org/en/20/orm/session_api.html#sqlalchemy.orm.Session.expire" target="_blank">https://docs.sqlalchemy.org/en/20/orm/session_api.html#sqlalchemy.orm.Session.expire</a></span><span data-type="text"></span></section><ol start="2" class="list-paddingleft-1"><li><p style="margin-bottom: 8px;margin-top: 16px;"><span data-type="text">select 查询时，设置</span><code data-type="inlineCode">execution_options</code><span data-type="text">的</span><code data-type="inlineCode">populate_existing</code><span data-type="text">参数为 True，强制 refresh</span></p></li></ol><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="sql"><section style="margin-bottom: 8px;"><code><span class="code-snippet_outer">stmt = (</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">select</span>(<span class="code-snippet__keyword">User</span>)</span></code><code><span class="code-snippet_outer">    .where(User.id == <span class="code-snippet__number">2</span>)</span></code><code><span class="code-snippet_outer">    .execution_options(populate_existing=<span class="code-snippet__literal">True</span>)</span></code><code><span class="code-snippet_outer">)</span></code></section></pre></section><section style="text-align: left;margin-bottom: 8px;"><span data-type="text">参考 </span><span data-type="text"><a href="https://docs.sqlalchemy.org/en/20/orm/queryguide/api.html#populate-existing" target="_blank">https://docs.sqlalchemy.org/en/20/orm/queryguide/api.html#populate-existing</a></span><span data-type="text"></span></section><p style="text-align: left;margin-bottom: 8px;margin-top: 24px;"><span data-type="text">以上两种方法均为单次生效，需要额外函数调用和参数设置，容易遗忘出错。而对于用户来说，多次查询同一个主键的数据时，预期的默认行为也是获取最新的值和刷新内存中的 object。因此更合适的解决方法是在创建 db engine 时就进行设置，代码示例如下</span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="python"><section style="margin-bottom: 8px;"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">from</span> sqlalchemy <span class="code-snippet__keyword">import</span> create_engine</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">engine_kwargs.setdefault(<span class="code-snippet__string">&#34;execution_options&#34;</span>, {}).setdefault(</span></code><code><span class="code-snippet_outer">  <span class="code-snippet__string">&#34;populate_existing&#34;</span>, <span class="code-snippet__keyword">True</span></span></code><code><span class="code-snippet_outer">)</span></code><code><span class="code-snippet_outer">create_engine(**engine_kwargs)</span></code></section></pre></section><section style="text-align: left;margin-bottom: 8px;"><span data-type="text">参考 </span><span data-type="text"><a href="https://docs.sqlalchemy.org/en/20/core/engines.html#sqlalchemy.create_engine" target="_blank">https://docs.sqlalchemy.org/en/20/core/engines.html#sqlalchemy.create_engine</a></span><span data-type="text"></span></section><section style="text-align: left;margin-bottom: 8px;"><span data-type="text"><br/></span></section><section style="text-align: left;margin-bottom: 8px;"><strong><span data-type="text">延伸</span></strong><span data-type="text">：上述问题发生在“任务调度”场景，属于后台服务。对于需要直接处理用户请求的后端 API 服务，是否会存在类似的问题？</span></section><section style="text-align: left;margin-bottom: 8px;"><strong><span data-type="text">结论：</span></strong><span data-type="text">在处理一个 Web 请求时，会创建独立的 scoped_session 来进行数据库的相关操作，并在 Web 请求结束后销毁。即处理不同用户请求的 session 不同，互不影响。在处理请求的过程中，对于用户侧功能，只会访问对应租户的 DB，因此不会出现该问题。在管理侧功能，会有手动切换和指定 DB 的操作，则可能会出现。因此建议参考前面的方法，在初始化数据库 engine 时，将 populate_existing 的默认值设置为 True</span></section><section style="text-align: left;margin-bottom: 8px;"><span data-type="text" style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;">参考 </span><span data-type="text" style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;"><a href="https://docs.sqlalchemy.org/en/20/orm/contextual.html#using-thread-local-scope-with-web-applications" target="_blank">https://docs.sqlalchemy.org/en/20/orm/contextual.html#using-thread-local-scope-with-web-applications</a></span></section><h1 style="font-size: 20pt;line-height: 85%;margin-top: 26.6667px;text-align: left;margin-bottom: 16px;"><span data-type="text" style="font-weight:bold;font-size:20pt;">0x05. 总结</span></h1><hr style="border-style: solid;border-width: 1px 0 0;border-color: rgba(0,0,0,0.1);-webkit-transform-origin: 0 0;-webkit-transform: scale(1, 0.5);transform-origin: 0 0;transform: scale(1, 0.5);"/><section style="text-align: left;margin-top: 16px;"><span data-type="text">本文分享了 SaaS 多租户自动化渗透平台在数据安全隔离方面的设计思路、代码实践步骤、以及因数据库框架默认特性导致“跨租户数据越权访问”安全问题的排查和解决过程。除了需要严格保障不同租户间无法访问到对方数据外，随着平台功能不断增加，租户内用户的权限控制和数据隔离也非常重要，且因业务需求多样化，会面临更多的挑战，后续有机会再单独进行讨论和介绍。</span></section><p style="text-align: left;"><span data-type="text"><br/></span></p><p style="text-align: left;"><span data-type="text">PS：这里会不定期分享关于 SaaS 自动化渗透平台建设、安全研发的一些想法、实践和总结，感兴趣的朋友可以关注一下！（微信搜索 “b1ngz的笔记本”）</span></p><h1 style="font-size: 20pt;line-height: 85%;margin-top: 26.6667px;text-align: left;margin-bottom: 16px;"><span data-type="text" style="font-weight:bold;font-size:20pt;">0x06. 参考</span></h1><hr style="border-style: solid;border-width: 1px 0 0;border-color: rgba(0,0,0,0.1);-webkit-transform-origin: 0 0;-webkit-transform: scale(1, 0.5);transform-origin: 0 0;transform: scale(1, 0.5);"/><hr style="border-style: solid;border-width: 1px 0 0;border-color: rgba(0,0,0,0.1);-webkit-transform-origin: 0 0;-webkit-transform: scale(1, 0.5);transform-origin: 0 0;transform: scale(1, 0.5);"/><table><colgroup><col width="45"/><col width="256"/><col width="349"/><col width="52"/></colgroup><tbody><tr><td colspan="1" rowspan="1" style="overflow: hidden;border-color: rgb(0, 0, 0);padding: 4px 8px;vertical-align: top;" width="9"><p style="text-align: left;"><span data-type="text">1</span></p></td><td colspan="1" rowspan="1" style="overflow: hidden;border-color: rgb(0, 0, 0);padding: 4px 8px;vertical-align: top;" width="13"><p style="text-align: left;"><span data-type="text"></span><a href="https://mp.weixin.qq.com/s?__biz=MzkwNDE5NzUyMA==&amp;mid=2247483694&amp;idx=1&amp;sn=f790233f79f52fb60fcd1aefa25d4820&amp;scene=21#wechat_redirect" data-link-href-cangjie="https://mp.weixin.qq.com/s?__biz=MzkwNDE5NzUyMA==&amp;mid=2247483694&amp;idx=1&amp;sn=f790233f79f52fb60fcd1aefa25d4820&amp;scene=21#wechat_redirect" target="_blank" rel="noopener noreferrer" data-linktype="2"><span data-type="text">SaaS多租户自动化渗透平台-架构笔记</span></a><span data-type="text"></span></p><p style="text-align: left;"><span data-type="text"></span></p></td><td colspan="1" rowspan="1" style="overflow: hidden;border-color: rgb(0, 0, 0);padding: 4px 8px;vertical-align: top;" width="211"><p style="text-align: left;"><span data-type="text"></span><a href="https://mp.weixin.qq.com/s?__biz=MzkwNDE5NzUyMA==&amp;mid=2247483694&amp;idx=1&amp;sn=f790233f79f52fb60fcd1aefa25d4820&amp;scene=21#wechat_redirect" data-link-href-cangjie="https://mp.weixin.qq.com/s?__biz=MzkwNDE5NzUyMA==&amp;mid=2247483694&amp;idx=1&amp;sn=f790233f79f52fb60fcd1aefa25d4820&amp;scene=21#wechat_redirect" target="_blank" rel="noopener noreferrer" data-linktype="2"><span data-type="text">https://mp.weixin.qq.com/s/FNr3TsiZU371F_44WelZbw</span></a><span data-type="text"></span></p></td></tr><tr><td colspan="1" rowspan="1" style="overflow: hidden;border-color: rgb(0, 0, 0);padding: 4px 8px;vertical-align: top;" width="9"><p style="text-align: left;"><span data-type="text">2</span></p></td><td colspan="1" rowspan="1" style="overflow: hidden;border-color: rgb(0, 0, 0);padding: 4px 8px;vertical-align: top;" width="13"><p style="text-align: left;"><span data-type="text">JWT attacks</span></p></td><td colspan="1" rowspan="1" style="overflow: hidden;border-color: rgb(0, 0, 0);padding: 4px 8px;vertical-align: top;" width="211"><p style="text-align: left;"><span data-type="text"></span><span data-type="text"><a href="https://portswigger.net/web-security/jwt" target="_blank">https://portswigger.net/web-security/jwt</a></span><span data-type="text"></span></p></td></tr><tr><td colspan="1" rowspan="1" style="overflow: hidden;border-color: rgb(0, 0, 0);padding: 4px 8px;vertical-align: top;" width="9"><p style="text-align: left;"><span data-type="text">3</span></p></td><td colspan="1" rowspan="1" style="overflow: hidden;border-color: rgb(0, 0, 0);padding: 4px 8px;vertical-align: top;" width="13"><p style="text-align: left;"><span data-type="text">Flask  Application Context</span></p></td><td colspan="1" rowspan="1" style="overflow: hidden;border-color: rgb(0, 0, 0);padding: 4px 8px;vertical-align: top;" width="211"><p style="text-align: left;"><span data-type="text"></span><span data-type="text"><a href="https://flask.palletsprojects.com/en/3.0.x/appcontext/" target="_blank">https://flask.palletsprojects.com/en/3.0.x/appcontext/</a></span><span data-type="text"></span></p></td></tr><tr><td colspan="1" rowspan="1" style="overflow: hidden;border-color: rgb(0, 0, 0);padding: 4px 8px;vertical-align: top;" width="9"><p style="text-align: left;"><span data-type="text">4</span></p></td><td colspan="1" rowspan="1" style="overflow: hidden;border-color: rgb(0, 0, 0);padding: 4px 8px;vertical-align: top;" width="13"><p style="text-align: left;"><span data-type="text">Flask g proxy object</span></p></td><td colspan="1" rowspan="1" style="overflow: hidden;border-color: rgb(0, 0, 0);padding: 4px 8px;vertical-align: top;" width="211"><p style="text-align: left;"><span data-type="text"></span><span data-type="text"><a href="https://flask.palletsprojects.com/en/3.0.x/api/#flask.g" target="_blank">https://flask.palletsprojects.com/en/3.0.x/api/#flask.g</a></span><span data-type="text"></span></p></td></tr><tr><td colspan="1" rowspan="1" style="overflow: hidden;border-color: rgb(0, 0, 0);padding: 4px 8px;vertical-align: top;" width="9"><p style="text-align: left;"><span data-type="text">5</span></p></td><td colspan="1" rowspan="1" style="overflow: hidden;border-color: rgb(0, 0, 0);padding: 4px 8px;vertical-align: top;" width="13"><p style="text-align: left;"><span data-type="text">Dramatiq Middleware</span></p></td><td colspan="1" rowspan="1" style="overflow: hidden;border-color: rgb(0, 0, 0);padding: 4px 8px;vertical-align: top;" width="211"><p style="text-align: left;"><span data-type="text"></span><span data-type="text"><a href="https://dramatiq.io/reference.html#middleware" target="_blank">https://dramatiq.io/reference.html#middleware</a></span><span data-type="text"></span></p></td></tr><tr><td colspan="1" rowspan="1" style="overflow: hidden;border-color: rgb(0, 0, 0);padding: 4px 8px;vertical-align: top;" width="9"><p style="text-align: left;"><span data-type="text">6</span></p></td><td colspan="1" rowspan="1" style="overflow: hidden;border-color: rgb(0, 0, 0);padding: 4px 8px;vertical-align: top;" width="13"><p style="text-align: left;"><span data-type="text">SQLAlchemy Session</span></p></td><td colspan="1" rowspan="1" style="overflow: hidden;border-color: rgb(0, 0, 0);padding: 4px 8px;vertical-align: top;" width="211"><p style="text-align: left;"><span data-type="text"></span><span data-type="text"><a href="https://docs.sqlalchemy.org/en/20/orm/session_basics.html" target="_blank">https://docs.sqlalchemy.org/en/20/orm/session_basics.html</a></span><span data-type="text"></span></p></td></tr><tr><td colspan="1" rowspan="1" style="overflow: hidden;border-color: rgb(0, 0, 0);padding: 4px 8px;vertical-align: top;" width="9"><p style="text-align: left;"><span data-type="text">7</span></p></td><td colspan="1" rowspan="1" style="overflow: hidden;border-color: rgb(0, 0, 0);padding: 4px 8px;vertical-align: top;" width="13"><p style="text-align: left;"><span data-type="text">SQLAlchemy Engine</span></p></td><td colspan="1" rowspan="1" style="overflow: hidden;border-color: rgb(0, 0, 0);padding: 4px 8px;vertical-align: top;" width="211"><p style="text-align: left;"><span data-type="text"></span><span data-type="text"><a href="https://docs.sqlalchemy.org/en/20/core/engines.html" target="_blank">https://docs.sqlalchemy.org/en/20/core/engines.html</a></span><span data-type="text"></span></p></td></tr><tr><td colspan="1" rowspan="1" style="overflow: hidden;border-color: rgb(0, 0, 0);padding: 4px 8px;vertical-align: top;" width="9"><p style="text-align: left;"><span data-type="text">8</span></p></td><td colspan="1" rowspan="1" style="overflow: hidden;border-color: rgb(0, 0, 0);padding: 4px 8px;vertical-align: top;" width="13"><p style="text-align: left;"><span data-type="text">SQLAlchemy ORM Populate Existing</span></p></td><td colspan="1" rowspan="1" style="overflow: hidden;border-color: rgb(0, 0, 0);padding: 4px 8px;vertical-align: top;" width="211"><p style="text-align: left;"><span data-type="text"></span><span data-type="text"><a href="https://docs.sqlalchemy.org/en/20/orm/queryguide/api.html#populate-existing" target="_blank">https://docs.sqlalchemy.org/en/20/orm/queryguide/api.html#populate-existing</a></span><span data-type="text"></span></p></td></tr><tr><td colspan="1" rowspan="1" style="overflow: hidden;border-color: rgb(0, 0, 0);padding: 4px 8px;vertical-align: top;" width="9"><p style="text-align: left;"><span data-type="text">9</span></p></td><td colspan="1" rowspan="1" style="overflow: hidden;border-color: rgb(0, 0, 0);padding: 4px 8px;vertical-align: top;" width="13"><p style="text-align: left;"><span data-type="text">SQLAlchemy Using Thread-Local Scope with Web Applications</span></p></td><td colspan="1" rowspan="1" style="overflow: hidden;border-color: rgb(0, 0, 0);padding: 4px 8px;vertical-align: top;" width="211"><p style="text-align: left;"><span data-type="text"></span><span data-type="text"><a href="https://docs.sqlalchemy.org/en/20/orm/contextual.html#using-thread-local-scope-with-web-applications" target="_blank">https://docs.sqlalchemy.org/en/20/orm/contextual.html#using-thread-local-scope-with-web-applications</a></span><span data-type="text"></span></p></td></tr></tbody></table><p style="text-align: left;"><span data-type="text"></span></p><p style="text-align: left;"><span data-type="text"></span></p></article><p><br/></p><p><br/></p><p style="display: none;"><mp-style-type data-value="3"></mp-style-type></p>



<p><a href="2247483699">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=2a50facc&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzkwNDE5NzUyMA%3D%3D%26mid%3D2247483699%26idx%3D1%26sn%3D3d35c690bff8246d0f8e320c59108828%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Fri, 27 Sep 2024 17:00:00 +0800</pubDate>
    </item>
    <item>
      <title>SaaS多租户自动化渗透平台-架构笔记</title>
      <link>https://mp.weixin.qq.com/s?__biz=MzkwNDE5NzUyMA==&amp;mid=2247483694&amp;idx=1&amp;sn=f790233f79f52fb60fcd1aefa25d4820</link>
      <description>文章介绍了为满足商业化需求，同时解决历史架构设计和技术选型问题的背景下，我和团队师傅在 SaaS 自动化渗透平台架构设计的又一次探索和实践，包括重构背后的一些思考、新架构的设计思路，以及架构的整体情况</description>
      <content:encoded><![CDATA[<p>
原创 <span>b1ngz</span> <span>2024-08-28 17:00</span> <span style="display: inline-block;">北京</span>
</p>

<p>文章介绍了为满足商业化需求，同时解决历史架构设计和技术选型问题的背景下，我和团队师傅在 SaaS 自动化渗透平台架构设计的又一次探索和实践，包括重构背后的一些思考、新架构的设计思路，以及架构的整体情况</p>
<p></p>



<p>
<img src="https://wechat2rss.xlab.app/img-proxy/?k=b487e899&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F1JicUwKQqRQ5hTLganMZaSHT8NXyajiagnbhZU3GezrBhflRfDIHsbTeU8dmbfRaibUwFZfpfHo2lzyuiaPC5DT5gA%2F0%3Fwx_fmt%3Djpeg"/>
</p>


<p style="margin-bottom: 16px;"><span data-type="text" style="font-size: 20pt;text-align: left;font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;letter-spacing: 0.034em;font-weight: bold;">0x01. 简介</span></p><hr style="border-style: solid;border-width: 1px 0 0;border-color: rgba(0,0,0,0.1);-webkit-transform-origin: 0 0;-webkit-transform: scale(1, 0.5);transform-origin: 0 0;transform: scale(1, 0.5);"/><section style="margin-bottom: 16px;"><span data-type="text" style="font-size: 20pt;text-align: left;font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;letter-spacing: 0.034em;font-weight: bold;"></span></section><section style="margin-bottom: 8px;line-height: 1.6em;"><span data-type="text" style="text-align: left;font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;">在 2022 年初，我写了一篇 “</span><a href="https://mp.weixin.qq.com/s?__biz=MzkwNDE5NzUyMA==&amp;mid=2247483673&amp;idx=1&amp;sn=88b42a078e291a2f9b3ef8de515731cf&amp;scene=21#wechat_redirect" data-link-href-cangjie="https://mp.weixin.qq.com/s?__biz=MzkwNDE5NzUyMA==&amp;mid=2247483673&amp;idx=1&amp;sn=88b42a078e291a2f9b3ef8de515731cf&amp;scene=21#wechat_redirect" target="_blank" rel="noopener noreferrer" data-linktype="2" style="text-align: left;font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;"><span data-type="text">云化分布式自动化渗透测试平台 - 架构笔记</span></a><span data-type="text" style="text-align: left;font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;">” ，介绍了我与</span><span data-type="text" style="text-align: left;font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.75pt;">团队师傅在 SaaS 自动化渗透平台架构设计方面的一些想法和初步实践</span><span data-type="text" style="text-align: left;font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;">，距今已过去两年多的时间。在这段时间里，遇到了很多新的问题和挑战，同时也有很多新的想法。在 23 年底，经过内部讨论，并结合业务发展情况，我们对整个平台进行了一次完全的重构，这篇笔记介绍了重构背后的一些思考、新架构的设计思路，以及架构的整体情况</span></section><article data-clipboard-cangjie="[&#34;root&#34;,{},[&#34;p&#34;,{&#34;uuid&#34;:&#34;lzi6kfaebony1lcvbof&#34;,&#34;ind&#34;:{&#34;left&#34;:0}},[&#34;span&#34;,{&#34;data-type&#34;:&#34;text&#34;},[&#34;span&#34;,{&#34;data-type&#34;:&#34;leaf&#34;},&#34;在 2022 年初，我写了一篇 “&#34;]],[&#34;a&#34;,{&#34;href&#34;:&#34;https://mp.weixin.qq.com/s/HmPLUNDbasuzGHS4K1IG5Q&#34;,&#34;uuid&#34;:&#34;lzi8b72fajmbmfgc4zb&#34;},[&#34;span&#34;,{&#34;data-type&#34;:&#34;text&#34;},[&#34;span&#34;,{&#34;data-type&#34;:&#34;leaf&#34;},&#34;云化分布式自动化渗透测试平台 - 架构笔记&#34;]]],[&#34;span&#34;,{&#34;data-type&#34;:&#34;text&#34;},[&#34;span&#34;,{&#34;data-type&#34;:&#34;leaf&#34;},&#34;” 文章，介绍了我与&#34;],[&#34;span&#34;,{&#34;spacing&#34;:0.75,&#34;data-type&#34;:&#34;leaf&#34;},&#34;团队师傅在SaaS自动化渗透平台架构设计方面的一些想法和初步实践&#34;],[&#34;span&#34;,{&#34;data-type&#34;:&#34;leaf&#34;},&#34;，距今已过去两年多的时间。在这段时间里，遇到了很多新的问题和挑战，同时也有很多新的想法。在 23 年底，经过内部讨论和结合业务发展情况，我们对整个平台进行了一次完全的重构，这篇笔记介绍了重构背后的一些思考、新架构的设计思路，以及架构的整体情况。&#34;]]],[&#34;p&#34;,{&#34;uuid&#34;:&#34;lzs6a2l1jh9ybejc5i&#34;,&#34;ind&#34;:{&#34;left&#34;:0}},[&#34;span&#34;,{&#34;data-type&#34;:&#34;text&#34;},[&#34;span&#34;,{&#34;data-type&#34;:&#34;leaf&#34;},&#34;PS：团队和公司有大量岗位招聘，可到 “0x06. 招聘” 查看&#34;]]]]" data-identifier-application__slash__x-doc-key="1X3lE6mYyLkGnJbv"><article data-clipboard-cangjie="[&#34;root&#34;,{},[&#34;p&#34;,{&#34;uuid&#34;:&#34;lzi6kfaebony1lcvbof&#34;,&#34;ind&#34;:{&#34;left&#34;:0}},[&#34;span&#34;,{&#34;data-type&#34;:&#34;text&#34;},[&#34;span&#34;,{&#34;data-type&#34;:&#34;leaf&#34;},&#34;在 2022 年初，我写了一篇 “&#34;]],[&#34;a&#34;,{&#34;href&#34;:&#34;https://mp.weixin.qq.com/s/HmPLUNDbasuzGHS4K1IG5Q&#34;,&#34;uuid&#34;:&#34;lzi8b72fajmbmfgc4zb&#34;},[&#34;span&#34;,{&#34;data-type&#34;:&#34;text&#34;},[&#34;span&#34;,{&#34;data-type&#34;:&#34;leaf&#34;},&#34;云化分布式自动化渗透测试平台 - 架构笔记&#34;]]],[&#34;span&#34;,{&#34;data-type&#34;:&#34;text&#34;},[&#34;span&#34;,{&#34;data-type&#34;:&#34;leaf&#34;},&#34;” 文章，介绍了我与&#34;],[&#34;span&#34;,{&#34;spacing&#34;:0.75,&#34;data-type&#34;:&#34;leaf&#34;},&#34;团队师傅在SaaS自动化渗透平台架构设计方面的一些想法和初步实践&#34;],[&#34;span&#34;,{&#34;data-type&#34;:&#34;leaf&#34;},&#34;，距今已过去两年多的时间。在这段时间里，遇到了很多新的问题和挑战，同时也有很多新的想法。在 23 年底，经过内部讨论和结合业务发展情况，我们对整个平台进行了一次完全的重构，这篇笔记介绍了重构背后的一些思考、新架构的设计思路，以及架构的整体情况。&#34;]]],[&#34;p&#34;,{&#34;uuid&#34;:&#34;lzs6a2l1jh9ybejc5i&#34;,&#34;ind&#34;:{&#34;left&#34;:0}},[&#34;span&#34;,{&#34;data-type&#34;:&#34;text&#34;},[&#34;span&#34;,{&#34;data-type&#34;:&#34;leaf&#34;},&#34;PS：团队和公司有大量岗位招聘，可到 “0x06. 招聘” 查看&#34;]]]]" data-identifier-application__slash__x-doc-key="1X3lE6mYyLkGnJbv"><p style="text-align: left;"><br/></p><p style="text-align: left;margin-bottom: 16px;"><span data-type="text">PS：<span style="font-family: &#34;PingFang SC&#34;, system-ui, -apple-system, &#34;system-ui&#34;, &#34;Helvetica Neue&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-weight: 700;letter-spacing: 0.578px;text-align: left;text-wrap: wrap;background-color: rgb(255, 255, 255);">🔥 </span>公司<span style="font-family: &#34;PingFang SC&#34;, system-ui, -apple-system, &#34;system-ui&#34;, &#34;Helvetica Neue&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;letter-spacing: 0.544px;text-align: left;text-wrap: wrap;background-color: rgb(255, 255, 255);">正在广纳人才</span>，详见 “0x06. 招聘” 或 复制访问下方链接<span style="letter-spacing: 0.578px;text-align: left;text-wrap: wrap;">在线查看</span><span style="text-align: left;text-wrap: wrap;font-family: &#34;PingFang SC&#34;, system-ui, -apple-system, &#34;system-ui&#34;, &#34;Helvetica Neue&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);">职位详情和<span style="letter-spacing: 0.544px;">投递</span>简历</span></span><span style="background-color: rgb(255, 255, 255);font-family: &#34;PingFang SC&#34;, system-ui, -apple-system, &#34;system-ui&#34;, &#34;Helvetica Neue&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;letter-spacing: 0.544px;font-size: var(--articleFontsize);"></span></p><p style="text-align: center;"> <span style="font-size: 18px;"><strong style="letter-spacing: 0.578px;text-align: left;text-wrap: wrap;color: rgb(255, 0, 0);"><a href="https://app.mokahr.com/su/5wsls " target="_blank">https://app.mokahr.com/su/5wsls </a></strong></span></p><p style="text-align: left;"><br/></p></article></article><article data-clipboard-cangjie="[&#34;root&#34;,{},[&#34;h1&#34;,{&#34;uuid&#34;:&#34;lz9ohwdg8whs2qpz22f&#34;,&#34;spacing&#34;:{&#34;before&#34;:26.666666666666664,&#34;after&#34;:9,&#34;line&#34;:0.8529411764705882}},[&#34;span&#34;,{&#34;data-type&#34;:&#34;text&#34;},[&#34;span&#34;,{&#34;bold&#34;:true,&#34;sz&#34;:20,&#34;szUnit&#34;:&#34;pt&#34;,&#34;data-type&#34;:&#34;leaf&#34;},&#34;0x02. 问题和挑战&#34;]]]]" data-identifier-application__slash__x-cangjie-fragment="JTdCJTIya2xhc3MlMjIlM0ElMjJkb2N1bWVudCUyMiUyQyUyMmRhdGElMjIlM0ElN0IlN0QlMkMlMjJub2RlcyUyMiUzQSU1QiU3QiUyMmtsYXNzJTIyJTNBJTIyYmxvY2slMjIlMkMlMjJ0eXBlJTIyJTNBJTIyaGVhZGluZy0xJTIyJTJDJTIyZGF0YSUyMiUzQSU3QiUyMnV1aWQlMjIlM0ElMjJsejlvaHdkZzh3aHMycXB6MjJmJTIyJTJDJTIyc3BhY2luZyUyMiUzQSU3QiUyMmJlZm9yZSUyMiUzQTI2LjY2NjY2NjY2NjY2NjY2NCUyQyUyMmFmdGVyJTIyJTNBOSUyQyUyMmxpbmUlMjIlM0EwLjg1Mjk0MTE3NjQ3MDU4ODIlN0QlN0QlMkMlMjJub2RlcyUyMiUzQSU1QiU3QiUyMmtsYXNzJTIyJTNBJTIydGV4dCUyMiUyQyUyMmxlYXZlcyUyMiUzQSU1QiU3QiUyMmtsYXNzJTIyJTNBJTIybGVhZiUyMiUyQyUyMnRleHQlMjIlM0ElMjIweDAyLiUyMCVFOSU5NyVBRSVFOSVBMiU5OCVFNSU5MiU4QyVFNiU4QyU5MSVFNiU4OCU5OCUyMiUyQyUyMm1hcmtzJTIyJTNBJTVCJTdCJTIya2xhc3MlMjIlM0ElMjJtYXJrJTIyJTJDJTIydHlwZSUyMiUzQSUyMmJvbGQlMjIlMkMlMjJkYXRhJTIyJTNBJTdCJTdEJTdEJTJDJTdCJTIya2xhc3MlMjIlM0ElMjJtYXJrJTIyJTJDJTIydHlwZSUyMiUzQSUyMnN6JTIyJTJDJTIyZGF0YSUyMiUzQSU3QiUyMnZhbHVlJTIyJTNBMjAlMkMlMjJzelVuaXQlMjIlM0ElMjJwdCUyMiU3RCU3RCU1RCU3RCU1RCU3RCU1RCU3RCU1RCU3RA==" data-identifier-application__slash__x-doc-key="1X3lE6mYyLkGnJbv"><h1 style="font-size: 20pt;line-height: 85%;margin-top: 26.6667px;margin-bottom: 9px;text-align: left;"><span data-type="text" style="font-weight:bold;font-size:20pt;"></span></h1></article><article data-identifier-application__slash__x-doc-key="1X3lE6mYyLkGnJbv"><h1 style="font-size: 20pt;line-height: 85%;margin-top: 26.6667px;text-align: left;margin-bottom: 24px;"><span data-type="text" style="font-weight:bold;font-size:20pt;"></span></h1><article data-clipboard-cangjie="[&#34;root&#34;,{},[&#34;h1&#34;,{&#34;uuid&#34;:&#34;lz9ohwdg8whs2qpz22f&#34;,&#34;spacing&#34;:{&#34;before&#34;:26.666666666666664,&#34;after&#34;:9,&#34;line&#34;:0.8529411764705882}},[&#34;span&#34;,{&#34;data-type&#34;:&#34;text&#34;},[&#34;span&#34;,{&#34;bold&#34;:true,&#34;sz&#34;:20,&#34;szUnit&#34;:&#34;pt&#34;,&#34;data-type&#34;:&#34;leaf&#34;},&#34;0x02. 问题和挑战&#34;]]],[&#34;p&#34;,{&#34;uuid&#34;:&#34;lzi9sfgjpr999asx3mn&#34;},[&#34;span&#34;,{&#34;data-type&#34;:&#34;text&#34;},[&#34;span&#34;,{&#34;data-type&#34;:&#34;leaf&#34;},&#34;在平台建设过程中，会有新需求不断的提出，和更复杂的业务场景需要满足，但平台架构很难在短时间内进行频繁改动。因此对于大多数情况，只能进行“修修补补”的操作，经过两年多的日积月累，历史架构设计和技术选型的问题逐步暴露，无法很好的满足业务发展的需求。&#34;]]]]" data-identifier-application__slash__x-doc-key="1X3lE6mYyLkGnJbv"><h1 style="font-size: 20pt;line-height: 85%;margin-top: 26.6667px;text-align: left;margin-bottom: 16px;"><span data-type="text" style="font-weight:bold;font-size:20pt;">0x02. 问题和挑战</span></h1><hr style="border-style: solid;border-width: 1px 0 0;border-color: rgba(0,0,0,0.1);-webkit-transform-origin: 0 0;-webkit-transform: scale(1, 0.5);transform-origin: 0 0;transform: scale(1, 0.5);"/><p style="text-align: left;"><span data-type="text"><br/></span></p><p style="text-align: left;"><span data-type="text">在平台建设过程中，会不断产生新的需求，和更复杂的业务场景需要满足，但平台架构很难在短时间内进行频繁改动。因此对于大多数情况，只能进行“修修补补”的操作，经过两年多的日积月累，历史架构设计和技术选型的问题逐步暴露，无法很好地满足业务发展的需求。</span></p></article><p style="text-align: left;"><span data-type="text"></span></p><p style="text-align: left;"><span data-type="text"><br/></span></p><section style="text-align: left;margin-bottom: 8px;"><span data-type="text">关于平台架构设计和技术选型部分的问题，可总结为：</span></section><ul class="list-paddingleft-1"><li><section style="margin-bottom: 8px;"><span data-type="text" style="font-weight:bold;">扫描节点无法独立部署：</span><span data-type="text">对于一个子任务的运行，可概括为三步 1. 从数据库查询所需参数，2. 执行具体逻辑，3. 保存结果入库。这里既有业务代码（1、3 两步，Python 编写），又包含引擎逻辑（第 2 步 GRPC 调用 Golang）。业务代码部分是一个大的后端项目，即节点的运行需要同时将后端和引擎服务运行起来，二者较为耦合，使得节点服务无法独立部署</span></section></li><li><section style="margin-bottom: 8px;"><span data-type="text" style="font-weight:bold;">扫描节点无法外置部署：</span><span data-type="text">因所有服务是在一个 VPC 内进行通信，节点执行任务需要访问 DB、队列等服务，但考虑到安全性、稳定性等原因，无法直接将服务暴露在公网，使得在目标存在网络访问限制（如只允许某个地区 IP 访问）、多云多地域出口 IP 等需求等场景下无法很好的支持。此外，外部环境可能是非受信环境，节点运行包含部分 Python 代码和配置，存在泄露风险</span></section></li><li><section style="margin-bottom: 8px;"><span data-type="text" style="font-weight:bold;">网络连接稳定性强依赖：</span><span data-type="text">起初选择了 RabbitMQ 作为消息队列，为了确保消息能成功的发送和执行，启用了双向 Ack，当 Client 与 Server 间的通信因为伸缩、维护、网络不稳定等不可避免原因出现中断时，RabbitMQ 会认为消费者异常（实际还在运行），从而将消息交由其他消费者处理，导致业务层和消息队列的状态不一致，出现一次任务多个运行实例的情况。此外，RabbitMQ 无法直接查看正在被执行的消息内容（unack 状态），无法自定义控制失败重试过程等限制，使得问题的排查、处理复杂和困难</span></section></li><li><section style="margin-bottom: 8px;"><span data-type="text" style="font-weight:bold;">后端框架不透明不灵活：</span><span data-type="text">此前我们选择了 Django REST Framework 作为后端业务层框架，借助成熟的生态和丰富的接口方法，实现了高效开发。但同时也存在一些问题，例如 Django ORM 提供的很多方法，内部都有一定程度的封装，会使得用户较难直观地知道背后的执行逻辑。在多人协作时，会给复杂需求代码实现 Review、问题定位排查和性能优化带来一定困难。此外，部分复杂的查询（如无 foreign key 表 join、自定义的 join 条件）在 Django ORM 下较难实现，灵活性上不足。而 Django/DRF 和 Django ORM 的强关联，使得集成和同时使用其他 DB 层框架等实现能力扩展的需求变得困难</span></section></li></ul><p style="text-align: left;"><span data-type="text"></span></p><p style="text-align: left;"><span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;"><br/></span></p><section style="text-align: left;margin-bottom: 8px;"><span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;">另一方面，平台在设计之初的定位是支撑内部渗透项目和攻防演练。而随着业务和平台的发展，内部也在考虑商业化的可行性，从而给平台带了新的需求和挑战</span><br/></section><ul class="list-paddingleft-1"><li><p style="margin-bottom: 8px;"><span data-type="text" style="font-weight:bold;">控制研发成本：</span><span data-type="text">因现有平台与内部系统有一定耦合，以及存在前述的设计和选型问题，无法直接进行改造后作为商业版。而开发和维护两套不同的平台，在现有人力下无法支撑。因此，需要考虑如何尽可能减少重复工作，降低开发和维护成本</span></p></li><li><section style="margin-bottom: 8px;"><span data-type="text" style="font-weight:bold;">数据安全保障：</span><span data-type="text">平台是 SaaS 化形态，数据存储在云端，客户对数据的安全性非常敏感，因此需要从设计上考虑安全隔离的方案，特别是不同客户间的数据隔离</span></section></li><li><section style="margin-bottom: 8px;"><span data-type="text" style="font-weight:bold;">合法合规保障：</span><span data-type="text">如果扫描流量走平台出口，会涉及到授权和法律风险。因此扫描节点需要由客户来提供，即需要能够支持扫描节点的私有化部署</span></section></li></ul></article><p><br/></p><article data-clipboard-cangjie="[&#34;root&#34;,{},[&#34;h1&#34;,{&#34;uuid&#34;:&#34;lz9ohwdg8whs2qpz22f&#34;,&#34;spacing&#34;:{&#34;before&#34;:26.666666666666664,&#34;after&#34;:9,&#34;line&#34;:0.8529411764705882}},[&#34;span&#34;,{&#34;data-type&#34;:&#34;text&#34;},[&#34;span&#34;,{&#34;bold&#34;:true,&#34;sz&#34;:20,&#34;szUnit&#34;:&#34;pt&#34;,&#34;data-type&#34;:&#34;leaf&#34;},&#34;0x02. 问题和挑战&#34;]]]]" data-identifier-application__slash__x-cangjie-fragment="JTdCJTIya2xhc3MlMjIlM0ElMjJkb2N1bWVudCUyMiUyQyUyMmRhdGElMjIlM0ElN0IlN0QlMkMlMjJub2RlcyUyMiUzQSU1QiU3QiUyMmtsYXNzJTIyJTNBJTIyYmxvY2slMjIlMkMlMjJ0eXBlJTIyJTNBJTIyaGVhZGluZy0xJTIyJTJDJTIyZGF0YSUyMiUzQSU3QiUyMnV1aWQlMjIlM0ElMjJsejlvaHdkZzh3aHMycXB6MjJmJTIyJTJDJTIyc3BhY2luZyUyMiUzQSU3QiUyMmJlZm9yZSUyMiUzQTI2LjY2NjY2NjY2NjY2NjY2NCUyQyUyMmFmdGVyJTIyJTNBOSUyQyUyMmxpbmUlMjIlM0EwLjg1Mjk0MTE3NjQ3MDU4ODIlN0QlN0QlMkMlMjJub2RlcyUyMiUzQSU1QiU3QiUyMmtsYXNzJTIyJTNBJTIydGV4dCUyMiUyQyUyMmxlYXZlcyUyMiUzQSU1QiU3QiUyMmtsYXNzJTIyJTNBJTIybGVhZiUyMiUyQyUyMnRleHQlMjIlM0ElMjIweDAyLiUyMCVFOSU5NyVBRSVFOSVBMiU5OCVFNSU5MiU4QyVFNiU4QyU5MSVFNiU4OCU5OCUyMiUyQyUyMm1hcmtzJTIyJTNBJTVCJTdCJTIya2xhc3MlMjIlM0ElMjJtYXJrJTIyJTJDJTIydHlwZSUyMiUzQSUyMmJvbGQlMjIlMkMlMjJkYXRhJTIyJTNBJTdCJTdEJTdEJTJDJTdCJTIya2xhc3MlMjIlM0ElMjJtYXJrJTIyJTJDJTIydHlwZSUyMiUzQSUyMnN6JTIyJTJDJTIyZGF0YSUyMiUzQSU3QiUyMnZhbHVlJTIyJTNBMjAlMkMlMjJzelVuaXQlMjIlM0ElMjJwdCUyMiU3RCU3RCU1RCU3RCU1RCU3RCU1RCU3RCU1RCU3RA==" data-identifier-application__slash__x-doc-key="1X3lE6mYyLkGnJbv"><article data-identifier-application__slash__x-doc-key="1X3lE6mYyLkGnJbv"><h1 style="font-size: 20pt;line-height: 85%;margin-top: 26.6667px;text-align: left;margin-bottom: 16px;"><strong><span data-type="text" style="font-weight:bold;font-size:20pt;">0x03. 解决</span><span data-type="text">思路</span></strong><span data-type="text"></span></h1><hr style="border-style: solid;border-width: 1px 0 0;border-color: rgba(0,0,0,0.1);-webkit-transform-origin: 0 0;-webkit-transform: scale(1, 0.5);transform-origin: 0 0;transform: scale(1, 0.5);"/><p><span data-type="text"></span></p><p style="text-align: left;"><span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;">对于上述问题和挑战，解决思路如下</span><span data-type="text"></span></p><p style="text-align: left;"><br/></p><ul class="list-paddingleft-1"><li><section style="margin-bottom: 8px;"><span data-type="text" style="font-weight:bold;">解耦扫描节点服务：</span><span data-type="text">将引擎和后端代码完全剥离，让扫描节点成为一个独立服务，即后端将子任务运行所需的所有参数发送给扫描节点，扫描节点仅负责执行，完成后将结果发送回后端服务，进行异步的处理和入库</span></section></li><li><section style="margin-bottom: 8px;"><span data-type="text" style="font-weight:bold;font-size:12pt;">打破VPC网络边界：</span><span data-type="text">对不适合直接暴露在公网上的服务（如消息队列）进行二次封装，使⽤如 HTTPS 等⽅式与 VPC 外部扫描节点进⾏通信，解决网络边界和安全性问题</span></section></li><li><section style="margin-bottom: 8px;"><span data-type="text" style="font-weight:bold;font-size:12pt;">替换消息队列实现：</span><span data-type="text" style="font-size:12pt;">基于 Redis Stream 开发新的消息队列服务，解决</span><span data-type="text">网络连接稳定性强依赖问题。并</span><span data-type="text" style="font-size:12pt;">实现更加灵活的消息发送、任务运行观测、失败重试控制等能力</span></section></li><li><section style="margin-bottom: 8px;"><span data-type="text" style="font-weight:bold;font-size:12pt;">替换后端开发框架：</span><span data-type="text">使用 Flask-RESTful + SQLAlchemy 代替 DRF 和 Django ORM，并参考 DRF View、</span><span data-type="text" style="font-size:12pt;">Serialize</span><span data-type="text">、FIlter 的设计，对 Flask-RESTful 进行封装，使得二者在写法上类似，更易上手</span></section></li><li><section style="margin-bottom: 8px;"><span data-type="text" style="font-weight:bold;font-size:12pt;">一套代码两个环境：</span><span data-type="text" style="font-size:12pt;">为了减少维护成本，这里采用只维护一套新平台代码的方案。但因内外部的功能和限制上有一些区别，这里通过角色权限和代码逻辑处理等方式来进行兼容</span><span data-type="text">。另外考虑到安全性，内外部是两套独立的环境，互不相通</span></section></li><li><section style="margin-bottom: 8px;"><span data-type="text" style="font-weight:bold;font-size:12pt;">多租户设计和改造：</span><span data-type="text">为了实现数据安全隔离，以及避免为每个客户搭建一套独立的环境导致维护成本过高，这里采用了存储层和扫描节点独立，其他服务共享的方案。即每个租户拥有独立的数据库、消息队列空间等，实现逻辑或实例级别的隔离。而对于后端 API、任务调度等服务，进行多租户的底层库封装（业务代码无感），支持根据用户或任务所属租户动态选择 DB，以及动态租户配置加载等能力</span></section></li><li><section style="margin-bottom: 8px;"><span data-type="text" style="font-weight:bold;font-size:12pt;">多种节点运行模式：</span><span data-type="text">对于商业版，主要以客户在自己的 ECS 实例上运行扫描节点的方式为主。在内部版，以 K8S 动态创建 Pod 的方式来实现更灵活高效的节点管理。此外，理论上只要部署环境能够运行 docker 容器，并且机器配置和网络带宽能满足需求，均可部署和运行扫描节点</span></section></li><li><section style="margin-bottom: 8px;"><span data-type="text" style="font-weight:bold;font-size:12pt;">构建安全中台服务：</span><span data-type="text" style="font-size:12pt;">因需要同时支撑内外部的使用需求，为了避免重复开发和实现无感的能力升级，这里将需要的公共安全能力抽取出来，统一到 SaaS 安全中台进行维护</span></section></li><li><section style="margin-bottom: 8px;"><span data-type="text" style="font-weight:bold;font-size:12pt;">开发运营运维平台：</span><span data-type="text">因多租户的设计，客户环境较多，为了能够高效方便的管理客户信息、环境配置，以及问题排查和定位，需要有一个上层的独立管理平台来进行支撑</span></section></li></ul><p style="text-align: left;"><br/></p></article><article data-identifier-application__slash__x-doc-key="1X3lE6mYyLkGnJbv"><h1 style="font-size: 20pt;line-height: 85%;margin-top: 26.6667px;text-align: left;margin-bottom: 16px;"><span data-type="text" style="font-weight:bold;font-size:20pt;">0x04. 平台架构</span></h1><hr style="border-style: solid;border-width: 1px 0 0;border-color: rgba(0,0,0,0.1);-webkit-transform-origin: 0 0;-webkit-transform: scale(1, 0.5);transform-origin: 0 0;transform: scale(1, 0.5);"/><p><span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;text-align: left;"><br/></span></p><p><span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;text-align: left;"><span style="letter-spacing: 0.578px;text-align: left;text-wrap: wrap;">新</span>平台架构示意图如下</span><br/></p><p><span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;text-align: left;"><br/></span></p><p style="text-align: left;"><span data-type="text"></span><img class="rich_pages wxw-img" data-imgfileid="100000042" data-ratio="0.9472222222222222" style="width:841px;height:797px;opacity:1;" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=398fcd42&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F1JicUwKQqRQ5hTLganMZaSHT8NXyajiagnbBEO9pSDsAp8G9W0Z6ugPbHfAicF5qujWKgzqz8TFKib9cNKQYQKe62A%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/><span data-type="text"></span></p><p style="text-align: left;"><span data-type="text"></span></p><p style="text-align: left;"><span data-type="text"><br/></span></p><section style="text-align: left;margin-bottom: 8px;"><span data-type="text">如上图所示，平台由四大部分组成</span></section><ol class="list-paddingleft-1"><li><section style="margin-bottom: 8px;"><span data-type="text" style="font-weight:bold;">SaaS 自动化渗透平台：</span><span data-type="text">图中蓝色部分，多租户架构设计，由业务层、存储层、基础服务、监控层等十余个服务组成，也是用户与平台交互的主要入口</span></section></li><li><section style="margin-bottom: 8px;"><span data-type="text" style="font-weight:bold;">外部扫描节点：</span><span data-type="text">图中右下角黄色部分，部署在不同云、环境下的扫描节点，通过 <span style="letter-spacing: 0.578px;text-wrap: wrap;">HTTPS</span> + 双向证书校验进行通信和身份认证</span></section></li><li><section style="margin-bottom: 8px;"><span data-type="text" style="font-weight:bold;">SaaS 安全中台：</span><span data-type="text">图中最上方绿色部分，通过 HTTPS 接口为内外部自动化渗透平台提供安全原子能力支撑</span></section></li><li><section style="margin-bottom: 8px;"><span data-type="text" style="font-weight:bold;">外部云基础设施：</span><span data-type="text">图中左下方橙色部分，通过云厂商 API 管理外部云资源，提供机器管理、代理服务、端口转发等功能</span></section></li></ol><p style="text-align: left;"><span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;"></span><span data-type="text" style="font-weight:bold;"></span></p><article data-clipboard-cangjie="[&#34;root&#34;,{},[&#34;p&#34;,{&#34;uuid&#34;:&#34;m0c34iy19muxi2sdpqg&#34;,&#34;ind&#34;:{&#34;left&#34;:0}},[&#34;span&#34;,{&#34;data-type&#34;:&#34;text&#34;},[&#34;span&#34;,{&#34;spacing&#34;:0.21675,&#34;data-type&#34;:&#34;leaf&#34;},&#34;这里对平台中关键服务和新增模块的功能进行进一步的介绍&#34;]]]]" data-identifier-application__slash__x-cangjie-fragment="JTdCJTIya2xhc3MlMjIlM0ElMjJkb2N1bWVudCUyMiUyQyUyMmRhdGElMjIlM0ElN0IlN0QlMkMlMjJub2RlcyUyMiUzQSU1QiU3QiUyMmtsYXNzJTIyJTNBJTIyYmxvY2slMjIlMkMlMjJ0eXBlJTIyJTNBJTIycGFyYWdyYXBoJTIyJTJDJTIyZGF0YSUyMiUzQSU3QiUyMnV1aWQlMjIlM0ElMjJtMGMzNGl5MTltdXhpMnNkcHFnJTIyJTJDJTIyaW5kJTIyJTNBJTdCJTIybGVmdCUyMiUzQTAlN0QlN0QlMkMlMjJub2RlcyUyMiUzQSU1QiU3QiUyMmtsYXNzJTIyJTNBJTIydGV4dCUyMiUyQyUyMmxlYXZlcyUyMiUzQSU1QiU3QiUyMmtsYXNzJTIyJTNBJTIybGVhZiUyMiUyQyUyMnRleHQlMjIlM0ElMjIlRTglQkYlOTklRTklODclOEMlRTUlQUYlQjklRTUlQjklQjMlRTUlOEYlQjAlRTQlQjglQUQlRTUlODUlQjMlRTklOTQlQUUlRTYlOUMlOEQlRTUlOEElQTElRTUlOTIlOEMlRTYlOTYlQjAlRTUlQTIlOUUlRTYlQTglQTElRTUlOUQlOTclRTclOUElODQlRTUlOEElOUYlRTglODMlQkQlRTglQkYlOUIlRTglQTElOEMlRTglQkYlOUIlRTQlQjglODAlRTYlQUQlQTUlRTclOUElODQlRTQlQkIlOEIlRTclQkIlOEQlMjIlMkMlMjJtYXJrcyUyMiUzQSU1QiU3QiUyMmtsYXNzJTIyJTNBJTIybWFyayUyMiUyQyUyMnR5cGUlMjIlM0ElMjJzcGFjaW5nJTIyJTJDJTIyZGF0YSUyMiUzQSU3QiUyMnZhbHVlJTIyJTNBMC4yMTY3NSU3RCU3RCU1RCU3RCU1RCU3RCU1RCUyQyUyMmNvbnRlbnRUeXBlJTIyJTNBJTIyY2FuZ2ppZS10ZXh0YmxvY2slMjIlN0QlNUQlN0Q=" data-identifier-application__slash__x-doc-key="1X3lE6mYyLkGnJbv"><p style="text-align: left;"><span data-type="text" style="letter-spacing:0.21675pt;"><br/></span></p><p style="text-align: left;"><span data-type="text" style="letter-spacing:0.21675pt;">这里对平台中关键服务和新增模块的功能进行进一步的介绍</span></p></article><p><br/></p><ul class="list-paddingleft-1"><li><p style="margin-bottom: 8px;"><span data-type="text" style="font-weight:bold;">扫描节点连接器：</span><span data-type="text">负责与扫描节点进行通信，包括任务获取、结果回传、状态回传、任务中止检查、节点更新等，同时对消息队列、存储服务等内部服务进行封装和屏蔽</span></p></li><li><section style="margin-bottom: 8px;"><span data-type="text" style="font-weight:bold;">消息队列：</span><span data-type="text">基于 Redis Stream 封装的消息队列服务，包括提供与队列通信的 API Server 和负责处理消息重回队列等后台任务的 Watcher 服务</span></section></li><li><section style="margin-bottom: 8px;"><span data-type="text" style="font-weight:bold;">扫描任务调度：</span><span data-type="text">根据配置的策略，对扫描任务进行调度，避免出现某个租户下的任务把所有资源占满等、实现动态调整租户任务并发能力等</span></section></li><li><section style="margin-bottom: 8px;"><span data-type="text" style="font-weight:bold;">结果处理：</span><span data-type="text">异步处理消息队列中的扫描任务执行结果，包括成功结果入库、任务状态 cache、ack 消息、失败消息重试等</span></section></li><li><section style="margin-bottom: 8px;"><span data-type="text" style="font-weight:bold;">队列监控：</span><span data-type="text">定时检查队列中消息是否存在异常，如是否有堆积、消息是否长时间未完成、消费者离线消息重回队列等</span></section></li><li><section style="margin-bottom: 8px;"><span data-type="text" style="font-weight:bold;">运营运维管理：</span><span data-type="text">独立平台，负责客户环境管理、用户管理、角色权限配置、配置管理、扫描节点监控、消息队列监控、更新部署、规则包管理和下发等</span></section></li></ul><p style="text-align: left;"><span data-type="text"></span></p><p style="text-align: left;"><span data-type="text"><br/></span></p><p style="text-align: left;"><span data-type="text">对于扫描子任务的运行过程，如下图所示</span></p><p style="text-align: left;"><span data-type="text"><br/></span></p><p style="text-align: left;"><span data-type="text"></span><img class="rich_pages wxw-img" data-imgfileid="100000041" data-ratio="0.6935185185185185" style="width:766px;height:531px;opacity:1;" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=1b84c98c&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F1JicUwKQqRQ5hTLganMZaSHT8NXyajiagn4nFEfXLGqX7fia19ibSImYz7AyJ2f8TM0QDYwlwoCj5Txo52dn50Kxfw%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/><span data-type="text"></span></p><p style="text-align: left;"><span data-type="text"></span></p><p style="text-align: left;"><span data-type="text"><br/></span></p><section style="text-align: left;margin-bottom: 8px;"><span data-type="text">图中包括 8 个步骤</span></section><ol class="list-paddingleft-2"><li><section style="margin-bottom: 8px;"><span data-type="text" style="font-weight:bold;">扫描任务</span><span data-type="text">通常包含多个步骤，每个步骤会将任务拆分成更小的单元，即子任务，发送到消息队列，进行并发执行</span></section></li><li><section style="margin-bottom: 8px;"><span data-type="text" style="font-weight:bold;">扫描节点</span><span data-type="text">定时请求节点连接器，获取要执行的子任务</span></section></li><li><section style="margin-bottom: 8px;"><span data-type="text" style="font-weight:bold;">节点连接器</span><span data-type="text">内部会根据节点所属的租户，查询对应的队列是否有消息，然后返回</span></section></li><li><section style="margin-bottom: 8px;"><span data-type="text" style="font-weight:bold;">扫描节点</span><span data-type="text">收到任务后，根据参数执行对应的操作</span></section></li><li><section style="margin-bottom: 8px;"><span data-type="text" style="font-weight:bold;">扫描节点</span><span data-type="text">执行完成后，会将执行情况回传给节点连接器，包括任务执行状态，任务结果等</span></section></li><li><section style="margin-bottom: 8px;"><span data-type="text" style="font-weight:bold;">节点连接器</span><span data-type="text">收到任务回传数据后，会进行</span></section></li><ol style="list-style-type:lower-alpha;" class="list-paddingleft-1"><li><section style="margin-bottom: 8px;"><span data-type="text">缓解队列消息状态，用于队列监控服务检查消息状态</span></section></li><li><section style="margin-bottom: 8px;"><span data-type="text">将结果存入消息队列，等待异步处理</span></section></li></ol><li><section style="margin-bottom: 8px;"><span data-type="text" style="font-weight:bold;">结果处理</span><span data-type="text">服务定时从消息队列中获取要处理的任务数据</span></section></li><li><section style="margin-bottom: 8px;"><span data-type="text" style="font-weight:bold;">结果处理</span><span data-type="text">服务首先会统一更新业务层任务状态，然后根据不同的任务状态进行不同的操作</span></section></li><ol style="list-style-type:lower-alpha;" class="list-paddingleft-1"><li><section style="margin-bottom: 8px;"><span data-type="text">任务成功：结果入库、ACK 队列消息</span></section></li><li><section style="margin-bottom: 8px;"><span data-type="text">任务失败：请求队列接口对消息进行 Delay 重试</span></section></li><li><section style="margin-bottom: 8px;"><span data-type="text">任务中止：ACK 队列消息</span></section></li></ol></ol></article><p><br/></p><article data-clipboard-cangjie="[&#34;root&#34;,{},[&#34;h1&#34;,{&#34;uuid&#34;:&#34;lz9oin07pswnbp2n9r&#34;,&#34;spacing&#34;:{&#34;before&#34;:26.666666666666664,&#34;after&#34;:9,&#34;line&#34;:0.8529411764705882}},[&#34;span&#34;,{&#34;data-type&#34;:&#34;text&#34;},[&#34;span&#34;,{&#34;bold&#34;:true,&#34;sz&#34;:20,&#34;szUnit&#34;:&#34;pt&#34;,&#34;data-type&#34;:&#34;leaf&#34;},&#34;0x05. 总结&#34;]]],[&#34;p&#34;,{&#34;uuid&#34;:&#34;lz9oicktv91j1a9y0a8&#34;},[&#34;span&#34;,{&#34;data-type&#34;:&#34;text&#34;},[&#34;span&#34;,{&#34;data-type&#34;:&#34;leaf&#34;},&#34;本文介绍了为满足商业化需求，同时解决历史架构设计和技术选型问题的背景下，我和团队师傅在 SaaS 自动化渗透平台架构设计的又一次探索和实践，重点解决了扫描节点私有化部署、多租户服务改造、多租户数据隔离等问题。目前新平台已基本成型，并投入使用，我们计划在后续推动旧版向新平台迁移，完成内外部版本的统一&#34;]]],[&#34;p&#34;,{&#34;uuid&#34;:&#34;m0c6rgp75w6hm7eesze&#34;},[&#34;span&#34;,{&#34;data-type&#34;:&#34;text&#34;},[&#34;span&#34;,{&#34;data-type&#34;:&#34;leaf&#34;},&#34;&#34;]]]]" data-identifier-application__slash__x-doc-key="1X3lE6mYyLkGnJbv"><h1 style="font-size: 20pt;line-height: 85%;margin-top: 26.6667px;text-align: left;margin-bottom: 16px;"><span data-type="text" style="font-weight:bold;font-size:20pt;">0x05. 总结</span></h1><hr style="border-style: solid;border-width: 1px 0 0;border-color: rgba(0,0,0,0.1);-webkit-transform-origin: 0 0;-webkit-transform: scale(1, 0.5);transform-origin: 0 0;transform: scale(1, 0.5);"/><p><span data-type="text" style="font-weight:bold;font-size:20pt;"></span></p><p style="text-align: left;"><span data-type="text">本文介绍了为满足商业化需求，同时解决历史架构设计和技术选型问题的背景下，我和团队师傅在 SaaS 自动化渗透平台架构设计的又一次探索和实践，重点解决了扫描节点私有化部署、多租户服务改造、多租户数据隔离等问题。目前新平台已基本成型，并投入使用，我们计划在后续推动旧版向新平台迁移，完成内外部版本的统一</span></p><p style="text-align: left;"><span data-type="text"></span></p><p style="text-align: left;"><span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;text-align: justify;">另外后续会不定期地分享关于 SaaS 自动化渗透平台建设和安全研发的一些实践经验和想法，感兴趣的朋友可以<span style="letter-spacing: 0.578px;text-wrap: wrap;">微信</span>扫码、或</span><span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;text-align: justify;">搜</span><span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;text-align: justify;">索 “b1ngz的笔记本”，关注一波！</span></p><p style="text-align: left;"><span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;text-align: justify;"><br/></span></p><p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-imgfileid="100000045" data-ratio="1.267515923566879" data-s="300,640" style="width: 240px;height: 304px;" data-type="png" data-w="157" src="https://wechat2rss.xlab.app/img-proxy/?k=43456fdd&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F1JicUwKQqRQ5hTLganMZaSHT8NXyajiagnLBs6Eic0MCdrLsNQSuia473CWt9yVkJHIoIFnVYRx653TNswLK9NCgAQ%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p style="text-align: center;"><br/></p></article></article><article data-identifier-application__slash__x-doc-key="1X3lE6mYyLkGnJbv"><h1 style="font-size: 20pt;line-height: 85%;margin-top: 26.6667px;text-align: left;margin-bottom: 16px;"><span data-type="text" style="font-weight:bold;font-size:20pt;">0x06. 招聘</span></h1><hr style="border-style: solid;border-width: 1px 0 0;border-color: rgba(0,0,0,0.1);-webkit-transform-origin: 0 0;-webkit-transform: scale(1, 0.5);transform-origin: 0 0;transform: scale(1, 0.5);"/><p><br/></p><p style="text-align: left;"><span style="font-weight: 700;letter-spacing: 0.578px;text-wrap: wrap;">🔥 </span>目前公司正在广纳人才，包括研发、安服、产品、销售、售前等多种类型数十个岗位，复制访问下方链接可看到在招职位详情和在线简历投递 </p><p style="text-align: left;"><strong style="color: rgb(255, 0, 0);font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;"></strong></p><p style="text-align: center;"><span style="color: rgb(255, 0, 0);font-size: 18px;"><strong><a href="https://app.mokahr.com/su/5wsls" target="_blank">https://app.mokahr.com/su/5wsls</a></strong></span></p><p style="text-align: left;"><br/></p><section style="text-align: left;margin-bottom: 8px;"><strong><span style="color: rgb(255, 0, 0);"><span style="font-weight: 700;letter-spacing: 0.578px;text-align: left;text-wrap: wrap;">🔥 </span>另外团队目前急招后端研发</span><span data-type="text"></span></strong><span data-type="text">，工作地点北京，团队介绍和 JD 如下，感兴趣的师傅可通过以下方式咨询和投递简历，同时也欢迎技术交流</span></section><ul class="list-paddingleft-1" style="list-style-type: disc;"><li><p>邮箱投递：binlin.yan@chaitin.com</p></li><li><p>微信投递：xiaobing1024</p></li></ul><p><br/></p><section style="text-align: left;margin-bottom: 8px;"><span data-type="text" style="font-weight:bold;font-size:12pt;">团队介绍：</span><span data-type="text" style="font-size:12pt;">我们是长亭科技-产品研发中心-协同创新团队，团队直线汇报给公司创始人</span></section><section style="text-align: left;margin-bottom: 8px;"><span data-type="text" style="font-weight:bold;font-size:12pt;">团队职责：</span><span data-type="text" style="font-size:12pt;">深入协同安服，将一线安全攻防经验，转换为自动化平台和工具，通过实战反馈，不断打磨优化，赋能公司业务，构筑公司核心竞争力。同时我们也在积极探索商业化，并取得不错的进展</span></section><section style="margin-bottom: 8px;"><span data-type="text" style="font-weight:bold;">团队项目：</span></section><ul class="list-paddingleft-1"><li><section style="margin-bottom: 8px;"><span data-type="text" style="font-weight:bold;">SaaS 自动化渗透平台：</span><span data-type="text">为安服渗透项目、攻防演练提供工具和平台支持，包括内部版、商业版</span></section></li><li><section style="margin-bottom: 8px;"><span data-type="text" style="text-align: left;font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;font-weight: bold;">攻防知识库：</span><span data-type="text" style="text-align: left;font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;">支撑公司各产品线的统一知识管理、运营、共享平台，包括漏洞、指纹、POC、利用等</span></section></li><li><section style="margin-bottom: 8px;"><span data-type="text" style="text-align: left;font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;font-weight: bold;">SaaS 安全实训平台</span><span data-type="text" style="text-align: left;font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;">：集学习、训练、考试一体化综合人才培养解决方案，包括内部版、商业版</span></section></li></ul><section style="text-align: left;margin-bottom: 8px;"><span data-type="text"></span></section><ul class="list-paddingleft-1"><li><section style="margin-bottom: 8px;"><span data-type="text" style="font-weight:bold;">比赛平台：</span><span data-type="text">为客户提供 CTF、AWD、安全运营等多赛制的一站式竞赛解决方案和平台支撑</span></section></li></ul><p><br/></p><section style="margin-bottom: 8px;"><span data-type="text" style="font-weight:bold;">🔥 后端研发 JD：</span></section><section style="margin-bottom: 8px;"><span data-type="text">注：可同时参与上述多个项目的后端开发</span></section><ol class="list-paddingleft-1"><li><section style="margin-bottom: 8px;"><span data-type="text">具有扎实的计算机基础、网络基础和编程基础</span></section></li><li><section style="margin-bottom: 8px;"><span data-type="text">掌握如 Python、Golang 等任意一门开发语言和相关 Web 框架，追求良好的代码风格和质量</span></section></li><li><section style="margin-bottom: 8px;"><span data-type="text">掌握如 PostgreSQL、Redis、Elasticsearch、MongoDB 等任意一种数据库的使用</span></section></li><li><section style="margin-bottom: 8px;"><span data-type="text">熟悉 Linux 环境操作，掌握 Git、Docker 等工具的使用</span></section></li><li><section style="margin-bottom: 8px;"><span data-type="text">具备较强的逻辑思维分析能力，对解决具有挑战性问题充满激情</span></section></li><li><section style="margin-bottom: 8px;"><span data-type="text">具有良好的沟通和团队协作能力、热爱技术、责任心强</span></section></li></ol><p style="text-align: left;"><br/></p><h1 style="font-size: 20pt;line-height: 85%;margin-top: 26.6667px;text-align: left;margin-bottom: 16px;"><span data-type="text" style="font-weight:bold;font-size:20pt;">0x07. 参考</span></h1><hr style="border-style: solid;border-width: 1px 0 0;border-color: rgba(0,0,0,0.1);-webkit-transform-origin: 0 0;-webkit-transform: scale(1, 0.5);transform-origin: 0 0;transform: scale(1, 0.5);"/><article data-clipboard-cangjie="[&#34;root&#34;,{},[&#34;p&#34;,{&#34;uuid&#34;:&#34;m0dkptz6hv6kana03ia&#34;,&#34;ind&#34;:{&#34;left&#34;:32}},[&#34;span&#34;,{&#34;data-type&#34;:&#34;text&#34;},[&#34;span&#34;,{&#34;data-type&#34;:&#34;leaf&#34;},&#34;&#34;]],[&#34;a&#34;,{&#34;href&#34;:&#34;https://mp.weixin.qq.com/s/OMhS9yFlcpI9KOQduSxq9g&#34;,&#34;uuid&#34;:&#34;m0dkpy32g2zgkwwxvdd&#34;},[&#34;span&#34;,{&#34;data-type&#34;:&#34;text&#34;},[&#34;span&#34;,{&#34;data-type&#34;:&#34;leaf&#34;},&#34;https://mp.weixin.qq.com/s/OMhS9yFlcpI9KOQduSxq9g&#34;]]],[&#34;span&#34;,{&#34;data-type&#34;:&#34;text&#34;},[&#34;span&#34;,{&#34;data-type&#34;:&#34;leaf&#34;},&#34;&#34;]]]]" data-identifier-application__slash__x-cangjie-fragment="JTdCJTIya2xhc3MlMjIlM0ElMjJkb2N1bWVudCUyMiUyQyUyMmRhdGElMjIlM0ElN0IlN0QlMkMlMjJub2RlcyUyMiUzQSU1QiU3QiUyMmtsYXNzJTIyJTNBJTIyYmxvY2slMjIlMkMlMjJ0eXBlJTIyJTNBJTIycGFyYWdyYXBoJTIyJTJDJTIyZGF0YSUyMiUzQSU3QiUyMnV1aWQlMjIlM0ElMjJtMGRrcHR6Nmh2NmthbmEwM2lhJTIyJTJDJTIyaW5kJTIyJTNBJTdCJTIybGVmdCUyMiUzQTMyJTdEJTdEJTJDJTIybm9kZXMlMjIlM0ElNUIlN0IlMjJrbGFzcyUyMiUzQSUyMnRleHQlMjIlMkMlMjJsZWF2ZXMlMjIlM0ElNUIlN0IlMjJrbGFzcyUyMiUzQSUyMmxlYWYlMjIlMkMlMjJ0ZXh0JTIyJTNBJTIyJTIyJTJDJTIybWFya3MlMjIlM0ElNUIlNUQlN0QlNUQlN0QlMkMlN0IlMjJrbGFzcyUyMiUzQSUyMmlubGluZSUyMiUyQyUyMnR5cGUlMjIlM0ElMjJsaW5rJTIyJTJDJTIyZGF0YSUyMiUzQSU3QiUyMmhyZWYlMjIlM0ElMjJodHRwcyUzQSUyRiUyRm1wLndlaXhpbi5xcS5jb20lMkZzJTJGT01oUzl5RmxjcEk5S09RZHVTeHE5ZyUyMiUyQyUyMnV1aWQlMjIlM0ElMjJtMGRrcHkzMmcyemdrd3d4dmRkJTIyJTdEJTJDJTIybm9kZXMlMjIlM0ElNUIlN0IlMjJrbGFzcyUyMiUzQSUyMnRleHQlMjIlMkMlMjJsZWF2ZXMlMjIlM0ElNUIlN0IlMjJrbGFzcyUyMiUzQSUyMmxlYWYlMjIlMkMlMjJ0ZXh0JTIyJTNBJTIyaHR0cHMlM0ElMkYlMkZtcC53ZWl4aW4ucXEuY29tJTJGcyUyRk9NaFM5eUZsY3BJOUtPUWR1U3hxOWclMjIlMkMlMjJtYXJrcyUyMiUzQSU1QiU1RCU3RCU1RCU3RCU1RCU3RCUyQyU3QiUyMmtsYXNzJTIyJTNBJTIydGV4dCUyMiUyQyUyMmxlYXZlcyUyMiUzQSU1QiU3QiUyMmtsYXNzJTIyJTNBJTIybGVhZiUyMiUyQyUyMnRleHQlMjIlM0ElMjIlMjIlMkMlMjJtYXJrcyUyMiUzQSU1QiU1RCU3RCU1RCU3RCU1RCUyQyUyMmNvbnRlbnRUeXBlJTIyJTNBJTIyY2FuZ2ppZS10ZXh0YmxvY2slMjIlN0QlNUQlN0Q=" data-identifier-application__slash__x-doc-key="1X3lE6mYyLkGnJbv"><p style="text-align: left;margin-left: 32px;"><br/></p></article><table style=""><tbody><tr><td width="31" valign="top" style="word-break: break-all;">1<br/></td><td width="249" valign="top" style="word-break: break-all;"><p><a href="https://mp.weixin.qq.com/s?__biz=MzkwNDE5NzUyMA==&amp;mid=2247483673&amp;idx=1&amp;sn=88b42a078e291a2f9b3ef8de515731cf&amp;scene=21#wechat_redirect" data-link-href-cangjie="https://mp.weixin.qq.com/s?__biz=MzkwNDE5NzUyMA==&amp;mid=2247483673&amp;idx=1&amp;sn=88b42a078e291a2f9b3ef8de515731cf&amp;scene=21#wechat_redirect" target="_blank" rel="noopener noreferrer" data-linktype="2" style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;text-wrap: wrap;"><span data-type="text">云化分布式自动化渗透测试平台 - 架构笔记</span></a></p><p><br/></p><article data-clipboard-cangjie="[&#34;root&#34;,{},[&#34;p&#34;,{&#34;uuid&#34;:&#34;lz9opvchcr5khz16vy&#34;,&#34;ind&#34;:{&#34;left&#34;:0}},[&#34;span&#34;,{&#34;data-type&#34;:&#34;text&#34;},[&#34;span&#34;,{&#34;data-type&#34;:&#34;leaf&#34;},&#34;&#34;]],[&#34;a&#34;,{&#34;href&#34;:&#34;https://mp.weixin.qq.com/s/OMhS9yFlcpI9KOQduSxq9g&#34;,&#34;uuid&#34;:&#34;m0diefl8cfls8qujw3e&#34;},[&#34;span&#34;,{&#34;data-type&#34;:&#34;text&#34;},[&#34;span&#34;,{&#34;data-type&#34;:&#34;leaf&#34;},&#34;自动化安全工具平台 - 架构笔记&#34;]]],[&#34;span&#34;,{&#34;data-type&#34;:&#34;text&#34;},[&#34;span&#34;,{&#34;data-type&#34;:&#34;leaf&#34;},&#34; &#34;]]]]" data-identifier-application__slash__x-cangjie-fragment="JTdCJTIya2xhc3MlMjIlM0ElMjJkb2N1bWVudCUyMiUyQyUyMmRhdGElMjIlM0ElN0IlN0QlMkMlMjJub2RlcyUyMiUzQSU1QiU3QiUyMmtsYXNzJTIyJTNBJTIyYmxvY2slMjIlMkMlMjJ0eXBlJTIyJTNBJTIycGFyYWdyYXBoJTIyJTJDJTIyZGF0YSUyMiUzQSU3QiUyMnV1aWQlMjIlM0ElMjJsejlvcHZjaGNyNWtoejE2dnklMjIlMkMlMjJpbmQlMjIlM0ElN0IlMjJsZWZ0JTIyJTNBMCU3RCU3RCUyQyUyMm5vZGVzJTIyJTNBJTVCJTdCJTIya2xhc3MlMjIlM0ElMjJ0ZXh0JTIyJTJDJTIybGVhdmVzJTIyJTNBJTVCJTdCJTIya2xhc3MlMjIlM0ElMjJsZWFmJTIyJTJDJTIydGV4dCUyMiUzQSUyMiUyMiUyQyUyMm1hcmtzJTIyJTNBJTVCJTVEJTdEJTVEJTdEJTJDJTdCJTIya2xhc3MlMjIlM0ElMjJpbmxpbmUlMjIlMkMlMjJ0eXBlJTIyJTNBJTIybGluayUyMiUyQyUyMmRhdGElMjIlM0ElN0IlMjJocmVmJTIyJTNBJTIyaHR0cHMlM0ElMkYlMkZtcC53ZWl4aW4ucXEuY29tJTJGcyUyRk9NaFM5eUZsY3BJOUtPUWR1U3hxOWclMjIlMkMlMjJ1dWlkJTIyJTNBJTIybTBkaWVmbDhjZmxzOHF1anczZSUyMiU3RCUyQyUyMm5vZGVzJTIyJTNBJTVCJTdCJTIya2xhc3MlMjIlM0ElMjJ0ZXh0JTIyJTJDJTIybGVhdmVzJTIyJTNBJTVCJTdCJTIya2xhc3MlMjIlM0ElMjJsZWFmJTIyJTJDJTIydGV4dCUyMiUzQSUyMiVFOCU4NyVBQSVFNSU4QSVBOCVFNSU4QyU5NiVFNSVBRSU4OSVFNSU4NSVBOCVFNSVCNyVBNSVFNSU4NSVCNyVFNSVCOSVCMyVFNSU4RiVCMCUyMC0lMjAlRTYlOUUlQjYlRTYlOUUlODQlRTclQUMlOTQlRTglQUUlQjAlMjIlMkMlMjJtYXJrcyUyMiUzQSU1QiU1RCU3RCU1RCU3RCU1RCU3RCUyQyU3QiUyMmtsYXNzJTIyJTNBJTIydGV4dCUyMiUyQyUyMmxlYXZlcyUyMiUzQSU1QiU3QiUyMmtsYXNzJTIyJTNBJTIybGVhZiUyMiUyQyUyMnRleHQlMjIlM0ElMjIlMjAlMjIlMkMlMjJtYXJrcyUyMiUzQSU1QiU1RCU3RCU1RCU3RCU1RCUyQyUyMmNvbnRlbnRUeXBlJTIyJTNBJTIyY2FuZ2ppZS10ZXh0YmxvY2slMjIlN0QlNUQlN0Q=" data-identifier-application__slash__x-doc-key="1X3lE6mYyLkGnJbv"><p style="text-align: left;"><span data-type="text"></span></p></article></td><td width="194" valign="top" style="word-break: break-all;"><section style="margin-bottom: 8px;"><a href="https://mp.weixin.qq.com/s?__biz=MzkwNDE5NzUyMA==&amp;mid=2247483673&amp;idx=1&amp;sn=88b42a078e291a2f9b3ef8de515731cf&amp;scene=21#wechat_redirect" data-link-href-cangjie="https://mp.weixin.qq.com/s?__biz=MzkwNDE5NzUyMA==&amp;mid=2247483673&amp;idx=1&amp;sn=88b42a078e291a2f9b3ef8de515731cf&amp;scene=21#wechat_redirect" target="_blank" rel="noopener noreferrer" data-linktype="2"><span data-type="text">https://mp.weixin.qq.com/s/HmPLUNDbasuzGHS4K1IG5Q</span></a></section></td></tr><tr><td width="40" valign="top" style="word-break: break-all;">2</td><td width="249" valign="top" style="word-break: break-all;"><p><a href="https://mp.weixin.qq.com/s?__biz=MzkwNDE5NzUyMA==&amp;mid=2247483657&amp;idx=1&amp;sn=890bfd44726b334ccaecc5195086aab4&amp;scene=21#wechat_redirect" data-link-href-cangjie="https://mp.weixin.qq.com/s?__biz=MzkwNDE5NzUyMA==&amp;mid=2247483657&amp;idx=1&amp;sn=890bfd44726b334ccaecc5195086aab4&amp;scene=21#wechat_redirect" target="_blank" rel="noopener noreferrer" style="text-align: left;font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;" data-linktype="2"><span data-type="text">自动化安全工具平台 - 架构笔记</span></a><br/></p></td><td width="194" valign="top" style="word-break: break-all;"><p><a href="https://mp.weixin.qq.com/s?__biz=MzkwNDE5NzUyMA==&amp;mid=2247483657&amp;idx=1&amp;sn=890bfd44726b334ccaecc5195086aab4&amp;scene=21#wechat_redirect" data-link-href-cangjie="https://mp.weixin.qq.com/s?__biz=MzkwNDE5NzUyMA==&amp;mid=2247483657&amp;idx=1&amp;sn=890bfd44726b334ccaecc5195086aab4&amp;scene=21#wechat_redirect" target="_blank" rel="noopener noreferrer" style="text-align: left;font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;" data-linktype="2"><span data-type="text">https://mp.weixin.qq.com/s/OMhS9yFlcpI9KOQduSxq9g</span></a><br/></p></td></tr><tr><td width="40" valign="top" style="word-break: break-all;">3</td><td width="229" valign="top" style="word-break: break-all;">RabbitMQ Consumer Acknowledgements and Publisher Confirms</td><td width="194" valign="top" style="word-break: break-all;"><a href="https://www.rabbitmq.com/docs/confirms" target="_blank">https://www.rabbitmq.com/docs/confirms</a></td></tr><tr><td width="40" valign="top" style="word-break: break-all;">4</td><td width="233" valign="top" style="word-break: break-all;">Flask-RESTful  </td><td width="194" valign="top" style="word-break: break-all;"><a href="https://flask-restful.readthedocs.io/en/latest/" target="_blank">https://flask-restful.readthedocs.io/en/latest/</a></td></tr><tr><td width="40" valign="top" style="word-break: break-all;">5<br/></td><td width="233" valign="top" style="word-break: break-all;">Django ORM vs SQLAlchemy </td><td width="194" valign="top" style="word-break: break-all;"><a href="https://ebs-integrator.com/en/blog/django-orm-vs-sql-alchemy" target="_blank">https://ebs-integrator.com/en/blog/django-orm-vs-sql-alchemy</a></td></tr><tr><td width="40" valign="top" style="word-break: break-all;">6</td><td width="229" valign="top" style="word-break: break-all;">Example of what SQLAlchemy can do, and Django ORM cannot </td><td width="194" valign="top" style="word-break: break-all;"><a href="https://stackoverflow.com/a/18207001" target="_blank">https://stackoverflow.com/a/18207001</a></td></tr><tr><td valign="top" colspan="1" rowspan="1" style="word-break: break-all;" width="25">7</td><td valign="top" colspan="1" rowspan="1" style="word-break: break-all;" width="229">SQLAlchemy - The Database Toolkit for Python </td><td valign="top" colspan="1" rowspan="1" style="word-break: break-all;" width="194"><a href="https://www.sqlalchemy.org/" target="_blank">https://www.sqlalchemy.org/</a></td></tr><tr><td valign="top" colspan="1" rowspan="1" style="word-break: break-all;" width="25">8<br/></td><td valign="top" colspan="1" rowspan="1" style="word-break: break-all;" width="229">What is multi-tenancy (multi-tenant architecture)? </td><td valign="top" colspan="1" rowspan="1" style="word-break: break-all;" width="194"><a href="https://www.techtarget.com/whatis/definition/multi-tenancy" target="_blank">https://www.techtarget.com/whatis/definition/multi-tenancy</a></td></tr><tr><td valign="top" colspan="1" rowspan="1" style="word-break: break-all;" width="25">9</td><td valign="top" colspan="1" rowspan="1" style="word-break: break-all;" width="229">Redis Stream </td><td valign="top" colspan="1" rowspan="1" style="word-break: break-all;" width="194"><a href="https://redis.io/docs/latest/develop/data-types/streams/" target="_blank">https://redis.io/docs/latest/develop/data-types/streams/</a></td></tr><tr><td valign="top" colspan="1" rowspan="1" style="word-break: break-all;" width="25">10</td><td valign="top" colspan="1" rowspan="1" style="word-break: break-all;" width="229">Low-latency message queue &amp; broker software</td><td valign="top" colspan="1" rowspan="1" style="word-break: break-all;" width="174"><a href="https://redis.io/solutions/messaging/" target="_blank">https://redis.io/solutions/messaging/</a></td></tr><tr><td valign="top" colspan="1" rowspan="1" style="word-break: break-all;" width="25">11<br/></td><td valign="top" colspan="1" rowspan="1" style="word-break: break-all;" width="229">Two-way SSL Authentication for REST </td><td valign="top" colspan="1" rowspan="1" style="word-break: break-all;" width="174"><a href="https://docs.solace.com/Security/Two-Way-SSL-Authentication.htm" target="_blank">https://docs.solace.com/Security/Two-Way-SSL-Authentication.htm</a></td></tr></tbody></table><article data-identifier-application__slash__x-doc-key="1X3lE6mYyLkGnJbv"><article data-identifier-application__slash__x-doc-key="1X3lE6mYyLkGnJbv"><ul class="list-paddingleft-1"><section style="margin-bottom: 8px;"><span data-type="text"></span></section></ul></article></article></article><p style="display: none;"><mp-style-type data-value="3"></mp-style-type></p>



<p><a href="2247483694">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=8a1d7c54&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzkwNDE5NzUyMA%3D%3D%26mid%3D2247483694%26idx%3D1%26sn%3Df790233f79f52fb60fcd1aefa25d4820%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Wed, 28 Aug 2024 17:00:00 +0800</pubDate>
    </item>
    <item>
      <title>云化分布式自动化渗透测试平台 - 架构笔记</title>
      <link>https://mp.weixin.qq.com/s?__biz=MzkwNDE5NzUyMA==&amp;mid=2247483673&amp;idx=1&amp;sn=88b42a078e291a2f9b3ef8de515731cf</link>
      <description></description>
      <content:encoded><![CDATA[<p>
原创 <span>b1ngz</span> <span>2022-01-05 18:14</span> <span style="display: inline-block;"></span>
</p>

<p></p>



<p>
<img src="https://wechat2rss.xlab.app/img-proxy/?k=e2e7802b&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F1JicUwKQqRQ6YLzsIgwEp8hQpAQOqCbaOG0Hg9Y267hlhDicGX5oRQXyBEoLJzYXkUw2BjRyJYubGCBN1zNBV23A%2F0%3Fwx_fmt%3Djpeg"/>
</p>


<section data-role="outer" label="Powered by 135editor.com"><section data-role="outer" label="Powered by 135editor.com" style=""><section data-role="paragraph"><section style="margin: 0px 8px;padding: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-align: justify;text-size-adjust: auto;text-decoration: none;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"><section style="margin: 0px 8px;padding: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-align: justify;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><section data-mid="t8" mpa-from-tpl="t" style="margin: 20px 0px 0px;padding: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;display: flex;-webkit-box-align: start;align-items: flex-start;-webkit-box-pack: start;justify-content: flex-start;"><section data-preserve-color="t" data-mid="" mpa-from-tpl="t" style="margin: 0px;padding: 0px 30px 0px 2px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;text-align: left;"><section data-preserve-color="t" data-mid="" mpa-from-tpl="t" style="margin: 0px;padding: 0px 30px 5px 2px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;font-size: 14px;color: #000000;border-bottom-width: 2px;border-bottom-style: solid;border-bottom-color: #000000;"><span style="margin: 0px;padding: 0px;max-width: 100%;font-size: 18px;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"><strong style="margin: 0px;padding: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;">0x01. 简介</strong></span></section></section></section></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br/></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="letter-spacing: 2px;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">在 2020 年 12 月，我写了公众号的第一篇文章 — “<a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzkwNDE5NzUyMA==&amp;mid=2247483657&amp;idx=1&amp;sn=890bfd44726b334ccaecc5195086aab4&amp;chksm=c08be5f6f7fc6ce069a2c2288f20d61537c5901686b95499dc1605de51afd3a0e6fd54ef2c6b&amp;scene=21#wechat_redirect" textvalue="自动化安全工具平台 - 架构笔记" linktype="text" imgurl="" imgdata="null" data-itemshowtype="0" tab="innerlink" data-linktype="2">自动化安全工具平台 - 架构笔记</a>”，文章介绍了前几年我在写个人自动化安全工具平台的过程中，关于架构方面的一些尝试和总结。也因这篇文章，在 2021 年 5 月，我有幸加入了长亭，负责红队自动化渗透测试平台项目。这篇笔记是近半年多来，我和团队师父们在平台架构方面的一些思考、尝试和总结，主要内容包括：</span></section><section data-role="list" style="box-sizing:border-box;color: #3e3e3e;margin: 0px auto;width: 95%;flex: 0 0 95%;" data-width="95%"><section data-role="list" data-width="100%" style="box-sizing:border-box;margin: 0px auto;width: 100%;flex: 0 0 100%;"><section data-role="list"><section data-role="list" data-width="100%" style="box-sizing:border-box;margin: 0px auto;width: 100%;flex: 0 0 100%;"><section data-role="list"><ul class="list-paddingleft-2" style="list-style-type: disc;margin: 0px;padding: 0px 0px 0px 30px;"><li><section dir="ltr" style="text-align: left;vertical-align: inherit;max-inline-size: 100%;margin: 0px 0px 0.5rem;padding-left: 0px;box-sizing: border-box;clear: both;white-space: pre-wrap;min-height: 1em;cursor: text;orphans: 4;line-height: 1.75em;outline: none 0px !important;"><span style="max-inline-size: 100%;margin: 0px;padding: 0px;box-sizing: border-box;cursor: text;font-size: 15px;outline: none 0px !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">如何理解云化分布式自动化渗透测试平台？</span></section></li><li><section dir="ltr" style="text-align: left;vertical-align: inherit;max-inline-size: 100%;margin: 0px 0px 0.5rem;padding-left: 0px;box-sizing: border-box;clear: both;white-space: pre-wrap;min-height: 1em;cursor: text;orphans: 4;line-height: 1.75em;outline: none 0px !important;"><span style="max-inline-size: 100%;margin: 0px;padding: 0px;box-sizing: border-box;cursor: text;font-size: 15px;outline: none 0px !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">平台架构介绍</span></section></li><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span md-inline="plain" style="box-sizing: border-box;">未来的一些想法和计划</span></section></li><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span md-inline="plain" style="box-sizing: border-box;">岗位招聘</span></section></li><li><section dir="ltr" style="text-align: left;vertical-align: inherit;max-inline-size: 100%;margin: 0px 0px 0.5rem;padding-left: 0px;box-sizing: border-box;clear: both;white-space: pre-wrap;min-height: 1em;cursor: text;orphans: 4;line-height: 1.75em;outline: none 0px !important;"><span style="max-inline-size: 100%;margin: 0px;padding: 0px;box-sizing: border-box;cursor: text;font-size: 15px;outline: none 0px !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">内容总结</span></section></li></ul></section><section dir="ltr" style="text-align: left;vertical-align: inherit;max-inline-size: 100%;margin: 0px 0px 0.5rem;padding-left: 0px;box-sizing: border-box;clear: both;white-space: pre-wrap;min-height: 1em;cursor: text;orphans: 4;line-height: 1.75em;outline: none 0px !important;"><br/></section></section></section></section></section></section></section><section style="margin: 0px 8px;padding: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-align: justify;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><section data-mid="t8" mpa-from-tpl="t" style="margin: 20px 0px 0px;padding: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;display: flex;-webkit-box-align: start;align-items: flex-start;-webkit-box-pack: start;justify-content: flex-start;"><section data-preserve-color="t" data-mid="" mpa-from-tpl="t" style="margin: 0px;padding: 0px 30px 0px 2px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;text-align: left;"><p style="vertical-align:inherit;margin: 0px;padding: 0px 30px 5px 2px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;font-size: 14px;color: #000000;border-bottom-width: 2px;border-bottom-style: solid;border-bottom-color: #000000;"><span style="margin: 0px;padding: 0px;max-width: 100%;font-size: 18px;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"><strong style="margin: 0px;padding: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;">0x02. 平台介绍</strong></span></p></section></section></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br/></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="letter-spacing: 2px;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">关于平台，这里结合文章标题中包含的关键词来进行介绍。</span></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 16px;"><strong style="letter-spacing: 2px;box-sizing: border-box;caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);orphans: 4;white-space: pre-wrap;text-size-adjust: auto;font-family: &#34;Open Sans&#34;, &#34;Clear Sans&#34;, &#34;Helvetica Neue&#34;, Helvetica, Arial, &#34;Segoe UI Emoji&#34;, sans-serif;"><span md-inline="plain" style="font-size: 16px;box-sizing: border-box;"><strong style="box-sizing: border-box;font-size: 16px;text-size-adjust: auto;"><span md-inline="plain" style="font-size: 16px;box-sizing: border-box;">关键词一：渗透测试平台</span></strong></span></strong></span><br/></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;letter-spacing: 2px;box-sizing: border-box;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">渗透测试平台相比于之前个人开发使用的安全工具平台，它主要的不同点在于：</span></section><section data-role="list" style="box-sizing:border-box;color: #3e3e3e;margin: 0px auto;width: 95%;flex: 0 0 95%;" data-width="95%"><section data-role="list" data-width="100%" style="box-sizing:border-box;margin: 0px auto;width: 100%;flex: 0 0 100%;"><section data-role="list"><section data-role="list"><section data-role="list"><ul class="list-paddingleft-2" style="list-style-type: disc;margin: 0px;padding: 0px 0px 0px 30px;"><li><section style="text-align: left;vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">渗透测试平台定位于为实际的安服项目、攻防演练提供支撑，需覆盖的场景更多，而后者主要满足个人平时的安全测试和挖洞</span></section></li><li><section style="text-align: left;vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">用户量更多，且为一线安全人员，平台功能更加丰富和贴近实战。随之复杂度也会增加，对平台的架构设计要求更高</span></section></li><li><section style="text-align: left;vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">有专人对接用户需求、协调试用和收集反馈，有更加充足的研发资源，实现更快的优化迭代速度，而后者需要个人拥有“全栈”技能</span></section></li></ul></section></section></section></section></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 16px;"><strong style="letter-spacing: 2px;box-sizing: border-box;caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);orphans: 4;white-space: pre-wrap;text-size-adjust: auto;font-family: &#34;Open Sans&#34;, &#34;Clear Sans&#34;, &#34;Helvetica Neue&#34;, Helvetica, Arial, &#34;Segoe UI Emoji&#34;, sans-serif;"><span md-inline="plain" style="font-size: 16px;box-sizing: border-box;"><strong style="box-sizing: border-box;font-size: 16px;text-size-adjust: auto;"><span md-inline="plain" style="font-size: 16px;box-sizing: border-box;"><br/></span></strong></span></strong></span></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 16px;"><strong style="letter-spacing: 2px;box-sizing: border-box;caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);orphans: 4;white-space: pre-wrap;text-size-adjust: auto;font-family: &#34;Open Sans&#34;, &#34;Clear Sans&#34;, &#34;Helvetica Neue&#34;, Helvetica, Arial, &#34;Segoe UI Emoji&#34;, sans-serif;"><span md-inline="plain" style="font-size: 16px;box-sizing: border-box;"><strong style="box-sizing: border-box;font-size: 16px;text-size-adjust: auto;"><span md-inline="plain" style="font-size: 16px;box-sizing: border-box;">关键词二：分布式</span></strong></span></strong></span><br/></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="letter-spacing: 2px;box-sizing: border-box;caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-weight: normal;orphans: 4;white-space: pre-wrap;text-size-adjust: auto;text-decoration: none;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">为了具备良好的扩展性，平台采用了分布式架构，利用消息队列解耦任务的发送和执行，通过增加消费者的数量，实现更高的扫描速度和并发支持。</span></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 16px;"><strong style="letter-spacing: 2px;box-sizing: border-box;caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);orphans: 4;white-space: pre-wrap;text-size-adjust: auto;font-family: &#34;Open Sans&#34;, &#34;Clear Sans&#34;, &#34;Helvetica Neue&#34;, Helvetica, Arial, &#34;Segoe UI Emoji&#34;, sans-serif;"><span md-inline="plain" style="font-size: 16px;box-sizing: border-box;"><strong style="box-sizing: border-box;font-size: 16px;text-size-adjust: auto;"><span md-inline="plain" style="font-size: 16px;box-sizing: border-box;"><br/></span></strong></span></strong></span></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 16px;"><strong style="letter-spacing: 2px;box-sizing: border-box;caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);orphans: 4;white-space: pre-wrap;text-size-adjust: auto;font-family: &#34;Open Sans&#34;, &#34;Clear Sans&#34;, &#34;Helvetica Neue&#34;, Helvetica, Arial, &#34;Segoe UI Emoji&#34;, sans-serif;"><span md-inline="plain" style="font-size: 16px;box-sizing: border-box;"><strong style="box-sizing: border-box;font-size: 16px;text-size-adjust: auto;"><span md-inline="plain" style="font-size: 16px;box-sizing: border-box;">关键词三：自动化</span></strong></span></strong></span><br/></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="letter-spacing: 2px;box-sizing: border-box;caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-weight: normal;orphans: 4;white-space: pre-wrap;text-size-adjust: auto;text-decoration: none;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">主要指渗透过程自动化，即如何减少渗透过程中的重复劳动，提高效率，让安全人员更专注于挖洞本身。广义上说，也包含研发、运维自动化，后续会在平台架构部分进行介绍。</span></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 16px;"><strong style="letter-spacing: 2px;box-sizing: border-box;caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);orphans: 4;white-space: pre-wrap;text-size-adjust: auto;font-family: &#34;Open Sans&#34;, &#34;Clear Sans&#34;, &#34;Helvetica Neue&#34;, Helvetica, Arial, &#34;Segoe UI Emoji&#34;, sans-serif;"><span md-inline="plain" style="font-size: 16px;box-sizing: border-box;"><strong style="box-sizing: border-box;font-size: 16px;text-size-adjust: auto;"><span md-inline="plain" style="font-size: 16px;box-sizing: border-box;"><br/></span></strong></span></strong></span></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 16px;"><strong style="letter-spacing: 2px;box-sizing: border-box;caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);orphans: 4;white-space: pre-wrap;text-size-adjust: auto;font-family: &#34;Open Sans&#34;, &#34;Clear Sans&#34;, &#34;Helvetica Neue&#34;, Helvetica, Arial, &#34;Segoe UI Emoji&#34;, sans-serif;"><span md-inline="plain" style="font-size: 16px;box-sizing: border-box;"><strong style="box-sizing: border-box;font-size: 16px;text-size-adjust: auto;"><span md-inline="plain" style="font-size: 16px;box-sizing: border-box;">关键词四：云化</span></strong></span></strong></span><br/></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="letter-spacing: 2px;box-sizing: border-box;caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-weight: normal;orphans: 4;white-space: pre-wrap;text-size-adjust: auto;text-decoration: none;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">即平台所有服务全部运行在云上。在上一篇架构笔记中，为了追求高可用，我曾自己搭建过 RabbitMQ 和 Postgresql 集群，机器成本相对于直接使用云厂商服务确实更低，但如服务升级、扩容、稳定性都需要自己来操作和保障，后期的运维成本更高。而全面上云后，大部分运维工作只需在页面上进行操作即可。通过借助云厂商更专业的服务，能够在提供高可用保障的同时，大幅减少运维成本。</span></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br/></section><section style="margin: 0px 8px;padding: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-align: justify;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><section data-mid="t8" mpa-from-tpl="t" style="margin: 20px 0px 0px;padding: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;display: flex;-webkit-box-align: start;align-items: flex-start;-webkit-box-pack: start;justify-content: flex-start;"><section data-preserve-color="t" data-mid="" mpa-from-tpl="t" style="margin: 0px;padding: 0px 30px 0px 2px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;text-align: left;"><p style="vertical-align:inherit;margin: 0px;padding-left: 2px;max-width: 100%;font-size: 14px;color: #000000;border-bottom: 2px solid #000000;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="margin: 0px;padding: 0px;max-width: 100%;font-size: 18px;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"><strong style="margin: 0px;padding: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;">0x03. 平台架构</strong></span></p></section></section></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br/></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="letter-spacing: 2px;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">目前平台架构如下图：</span></section><p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.6875" data-s="300,640" style="" data-type="png" data-w="1280" src="https://wechat2rss.xlab.app/img-proxy/?k=85e76242&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F1JicUwKQqRQ6YLzsIgwEp8hQpAQOqCbaOxWvLlVibuPUJJHe0KOJYfmMvGQaiaRZ7vLay5odEXrVzR3Vm4gwdjj0g%2F640%3Fwx_fmt%3Dpng"/></p><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br/></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="letter-spacing: 2px;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">平台同样采用前后端分离，开发语言和框架为：<br/></span></section><section data-role="list" style="box-sizing:border-box;color: #3e3e3e;margin: 0px auto;width: 95%;flex: 0 0 95%;" data-width="95%"><section data-role="list" data-width="100%" style="box-sizing:border-box;margin: 0px auto;width: 100%;flex: 0 0 100%;"><section data-role="list"><section data-role="list"><section data-role="list"><section data-role="list"><section data-role="list"><ul class="list-paddingleft-2" style="list-style-type: disc;margin: 0px;padding: 0px 0px 0px 30px;"><li><section style="vertical-align: inherit;line-height: 1.75em;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">前端：Vue + Element UI，语言方面为了代码更易维护，采用强类型的 TypeScript。</span></section></li><li><section style="vertical-align: inherit;line-height: 1.75em;"><span style="font-size: 15px;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"></span><span style="orphans: 4;white-space: pre-wrap;caret-color: red;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">后端：包含业务层和安全引擎两部分。业务侧追求开发速度，使用 Python 3.8 + Django REST framework。引擎侧关注效率使用 Golang，之间通过 gRPC 进行调用</span></span></section></li></ul></section></section></section></section></section></section></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;font-size: 15px;letter-spacing: 2px;"><br/></span></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;font-size: 15px;letter-spacing: 2px;">平台使用到的服务和组件信息如下：</span><br/></section><table width="100%"><tbody><tr><td valign="top" style="padding: 5px 10px;"><section style="line-height: 1.75em;"><span style="font-size: 15px;color: #626262;"><strong><span style="font-size: 15px;color: rgb(98, 98, 98);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">序号   </span></strong></span></section></td><td valign="top" style="padding: 5px 10px;"><section style="line-height: 1.75em;"><span style="color: #626262;"><strong><span style="font-size: 15px;color: rgb(98, 98, 98);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">服务                    </span></strong></span></section></td><td valign="top" style="padding: 5px 10px;"><section style="line-height: 1.75em;"><span style="color: #626262;"><strong><span style="font-size: 15px;color: rgb(98, 98, 98);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">说明</span></strong></span></section></td></tr><tr><td valign="top" style="padding: 5px 10px;"><section style="line-height: 1.75em;"><span style="font-size: 15px;color: rgb(98, 98, 98);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">1</span></section></td><td valign="top" style="padding: 5px 10px;"><section style="line-height: 1.75em;"><span style="font-size: 15px;color: rgb(98, 98, 98);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">Gitlab</span></section></td><td valign="top" style="padding: 5px 10px;"><section style="line-height: 1.75em;"><span style="font-size: 15px;color: rgb(98, 98, 98);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">代码托管，CI/CD 自动化构建</span></section></td></tr><tr><td valign="top" style="padding: 5px 10px;"><section style="line-height: 1.75em;"><span style="font-size: 15px;color: rgb(98, 98, 98);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">2</span></section></td><td valign="top" style="padding: 5px 10px;"><section style="line-height: 1.75em;"><span style="font-size: 15px;color: rgb(98, 98, 98);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">Image Registry</span></section></td><td valign="top" style="padding: 5px 10px;"><section style="line-height: 1.75em;"><span style="font-size: 15px;color: rgb(98, 98, 98);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">Docker 镜像仓库</span></section></td></tr><tr><td valign="top" style="padding: 5px 10px;"><section style="line-height: 1.75em;"><span style="font-size: 15px;color: rgb(98, 98, 98);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">3</span></section></td><td valign="top" style="padding: 5px 10px;"><section style="line-height: 1.75em;"><span style="font-size: 15px;color: rgb(98, 98, 98);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">Postgresql</span></section></td><td valign="top" style="padding: 5px 10px;"><section style="line-height: 1.75em;"><span style="font-size: 15px;color: rgb(98, 98, 98);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">关系型数据库，存储平台数据 </span></section></td></tr><tr><td valign="top" style="padding: 5px 10px;"><section style="line-height: 1.75em;"><span style="font-size: 15px;color: rgb(98, 98, 98);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">4</span></section></td><td valign="top" style="padding: 5px 10px;"><section style="line-height: 1.75em;"><span style="font-size: 15px;color: rgb(98, 98, 98);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">Redis</span></section></td><td valign="top" style="padding: 5px 10px;"><section style="line-height: 1.75em;"><span style="font-size: 15px;color: rgb(98, 98, 98);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">缓存服务</span></section></td></tr><tr><td valign="top" style="padding: 5px 10px;"><section style="line-height: 1.75em;"><span style="font-size: 15px;color: rgb(98, 98, 98);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">5</span></section></td><td valign="top" style="padding: 5px 10px;"><section style="line-height: 1.75em;"><span style="font-size: 15px;color: rgb(98, 98, 98);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">ELK Stack</span></section></td><td valign="top" style="padding: 5px 10px;"><section style="vertical-align: inherit;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(98, 98, 98);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">存储/查询 Http 请求响应数据</span><span style="color: rgb(98, 98, 98);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;font-size: 15px;">、业务日志</span></section></td></tr><tr><td valign="top" style="padding: 5px 10px;"><section style="line-height: 1.75em;"><span style="font-size: 15px;color: rgb(98, 98, 98);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">6</span></section></td><td valign="top" style="padding: 5px 10px;"><section style="line-height: 1.75em;"><span style="font-size: 15px;color: rgb(98, 98, 98);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">Object Storage</span></section></td><td valign="top" style="padding: 5px 10px;"><section style="vertical-align: inherit;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(98, 98, 98);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">存储用户上传、导出数据</span><span style="color: rgb(98, 98, 98);font-size: 15px;caret-color: red;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">、</span><span style="color: rgb(98, 98, 98);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;font-size: 15px;caret-color: red;">页面截图等</span></section></td></tr><tr><td valign="top" style="padding: 5px 10px;"><section style="line-height: 1.75em;"><span style="font-size: 15px;color: rgb(98, 98, 98);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">7</span></section></td><td valign="top" style="padding: 5px 10px;"><section style="line-height: 1.75em;"><span style="font-size: 15px;color: rgb(98, 98, 98);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">Sentry</span></section></td><td valign="top" style="padding: 5px 10px;"><section style="line-height: 1.75em;"><span style="font-size: 15px;color: rgb(98, 98, 98);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">代码错误监控和追踪</span></section></td></tr><tr><td valign="top" style="padding: 5px 10px;"><section style="line-height: 1.75em;"><span style="font-size: 15px;color: rgb(98, 98, 98);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">8</span></section></td><td valign="top" style="padding: 5px 10px;"><section style="line-height: 1.75em;"><span style="font-size: 15px;color: rgb(98, 98, 98);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">Frontend</span></section></td><td valign="top" style="padding: 5px 10px;"><section style="line-height: 1.75em;"><span style="font-size: 15px;color: rgb(98, 98, 98);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">Nginx 反向代理、静态资源访问</span></section></td></tr><tr><td valign="top" colspan="1" rowspan="1" style="padding: 5px 10px;"><section style="line-height: 1.75em;"><span style="font-size: 15px;color: rgb(98, 98, 98);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">9</span></section></td><td valign="top" colspan="1" rowspan="1" style="padding: 5px 10px;"><section style="line-height: 1.75em;"><span style="font-size: 15px;color: rgb(98, 98, 98);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">Backend</span></section></td><td valign="top" colspan="1" rowspan="1" style="padding: 5px 10px;"><section style="line-height: 1.75em;"><span style="font-size: 15px;color: rgb(98, 98, 98);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">后端 API Server，使用 DRF 框架</span></section></td></tr><tr><td valign="top" colspan="1" rowspan="1" style="padding: 5px 10px;"><section style="line-height: 1.75em;"><span style="font-size: 15px;color: rgb(98, 98, 98);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">10</span></section></td><td valign="top" colspan="1" rowspan="1" style="padding: 5px 10px;"><section style="line-height: 1.75em;"><span style="font-size: 15px;color: rgb(98, 98, 98);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">Prometheus</span></section></td><td valign="top" colspan="1" rowspan="1" style="padding: 5px 10px;"><section style="line-height: 1.75em;"><span style="font-size: 15px;color: rgb(98, 98, 98);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">指标统计监控、告警</span></section></td></tr><tr><td valign="top" colspan="1" rowspan="1" style="padding: 5px 10px;"><section style="line-height: 1.75em;"><span style="font-size: 15px;color: rgb(98, 98, 98);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">11</span></section></td><td valign="top" colspan="1" rowspan="1" style="padding: 5px 10px;"><section style="line-height: 1.75em;"><span style="font-size: 15px;color: rgb(98, 98, 98);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">RabbitMQ</span></section></td><td valign="top" colspan="1" rowspan="1" style="padding: 5px 10px;"><section style="line-height: 1.75em;"><span style="font-size: 15px;color: rgb(98, 98, 98);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">分布式消息代理</span></section></td></tr><tr><td valign="top" colspan="1" rowspan="1" style="padding: 5px 10px;"><section style="vertical-align: inherit;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(98, 98, 98);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">12</span></section></td><td valign="top" colspan="1" rowspan="1" style="padding: 5px 10px;"><section style="line-height: 1.75em;"><span style="font-size: 15px;color: rgb(98, 98, 98);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">Dramatiq</span></section></td><td valign="top" colspan="1" rowspan="1" style="padding: 5px 10px;"><section style="line-height: 1.75em;"><span style="font-size: 15px;color: rgb(98, 98, 98);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">Python 异步任务框架</span></section></td></tr><tr><td valign="top" colspan="1" rowspan="1" style="padding: 5px 10px;"><section style="line-height: 1.75em;"><span style="font-size: 15px;color: rgb(98, 98, 98);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">13</span></section></td><td valign="top" colspan="1" rowspan="1" style="padding: 5px 10px;"><section style="line-height: 1.75em;"><span style="font-size: 15px;color: rgb(98, 98, 98);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">Kubernates</span></section></td><td valign="top" colspan="1" rowspan="1" style="padding: 5px 10px;"><section style="line-height: 1.75em;"><span style="font-size: 15px;color: rgb(98, 98, 98);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">容器化部署管理</span></section></td></tr></tbody></table><section style="box-sizing: border-box;padding: 0px;border-style: none;border-width: 2px;border-color: rgb(255, 0, 0);border-radius: 0px;line-height: 1.75em;"><span style="letter-spacing: 2px;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"></span><span style="letter-spacing: 2px;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"></span></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br/></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="letter-spacing: 2px;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">从列表信息看，核心组件与个人版基本相同，此外还增加了多个新服务来完善平台的各项能力，如自动化构建、错误追踪、监控告警等。</span></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;font-size: 15px;letter-spacing: 2px;">从架构图右侧，可以明显看到前一章节提到的 “云化” 特点。</span><span style="font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;font-size: 15px;letter-spacing: 2px;">对于基础服务，如 Postgresql、Redis、ELK、对象存储等，都直接使用了云厂商提供的高可用集群版本，来保障平台的稳定性。</span><br/></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;font-size: 15px;letter-spacing: 2px;">另一个改进点是，平台使用了 kubernates 来进行服务的容器化部署和管理，相比于个人版基于 docker、docker-compose 的方案，k8s 的功能更加强大。</span><span style="font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;font-size: 15px;letter-spacing: 2px;">简单理解，你只需要通过 YAML 定义来声明需要的资源，如服务实例数量、机器资源、环境变量、启动命令等配置，k8s 会负责服务的启动、健康检查、故障迁移等剩余的工作。</span><span style="font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;font-size: 15px;letter-spacing: 2px;">在 k8s 中，Pod 是最基础的运行单元，此外还提供了多种内置的应用类型（workload）来满足常用的业务场景，以下为平台中的一些应用例子：</span><br/></section><section data-role="list" style="box-sizing:border-box;color: #3e3e3e;margin: 0px auto;width: 95%;flex: 0 0 95%;" data-width="95%"><section data-role="list" data-width="100%" style="box-sizing:border-box;margin: 0px auto;width: 100%;flex: 0 0 100%;"><section data-role="list"><section data-role="list"><section data-role="list"><section data-role="list"><section data-role="list"><section data-role="list"><ul class="list-paddingleft-2" style="list-style-type: disc;margin: 0px;padding: 0px 0px 0px 30px;"><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">业务服务（python）依赖引擎服务（golang），二者需要同时运行。类似 docker-compose，在 k8s 的 Pod 内可以运行两个 container，容器实例之间通过 localhost 进行相互访问</span></section></li><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="caret-color: red;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">对于如前端和后端 API server 服务，服务的实例之间没有本质区别，使用 Deployments 来部署</span></section></li><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="caret-color: red;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">对于如 RabbitMQ Cluster 服务，节点区分 master 和 slave，使用 StatefulSets 来运行</span></section></li></ul></section></section></section></section></section></section></section></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;font-size: 15px;letter-spacing: 2px;"><br/></span></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;font-size: 15px;letter-spacing: 2px;">在平台开发的过程中，也遇到过某些复杂功能，如实现为某个任务分配独享计算资源，需要能够自行控制节点（Pod）的创建过程，但内置的应用类型（workload）无法满足需求。</span><span style="font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;font-size: 15px;letter-spacing: 2px;">此时，可通过 k8s 强大的扩展能力 Custom Resources 和 Operator pattern，来定义自己的资源类型，编写 controller 来进行管理。</span><span style="font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;font-size: 15px;letter-spacing: 2px;">此外，k8s 还有如使用 Persistent Volumes 实现多个服务挂载和访问同一个存储磁盘、通过 kubectl scale 命令实现资源快速伸缩等功能，能极大的提升平台部署效率和扩展能力。</span><br/></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br/></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;font-size: 15px;letter-spacing: 2px;">下一个不同点是，个人版在后端开发时主要使用 Python 语言，利用协程 gevent、asyncio 来缓解 GIL 带来的并发性能问题。</span><span style="font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;font-size: 15px;letter-spacing: 2px;">而在新平台，我们对后端功能进行了拆分，使用 Golang 来进行安全引擎的开发，而业务层仍使用 Python，这样做的考虑主要有：</span><br/></section><section data-role="list" style="box-sizing:border-box;color: #3e3e3e;margin: 0px auto;width: 95%;flex: 0 0 95%;" data-width="95%"><section data-role="list" data-width="100%" style="box-sizing:border-box;margin: 0px auto;width: 100%;flex: 0 0 100%;"><section data-role="list"><section data-role="list"><ul class="list-paddingleft-2" style="list-style-type: disc;margin: 0px;padding: 0px 0px 0px 30px;"><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">Python 为解释型语言，动态类型开发速度快、灵活，但易出错。Golang 为编译型语言，静态类型让代码更易维护</span></section></li><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">Golang 拥有 goroutine 和 context，对并发的支持和控制更好，运行速度和效率要比 Python 更高</span></section></li><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">公司已有安全能力开发语言为 Golang，能进行复用和相互输出</span></section></li></ul></section></section></section></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;font-size: 15px;letter-spacing: 2px;"><br/></span></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;font-size: 15px;letter-spacing: 2px;">对于异步任务框架 Dramatiq，之前在个人版中遇到了一些问题：</span><br/></section><section data-role="list" style="box-sizing:border-box;color: #3e3e3e;margin: 0px auto;width: 95%;flex: 0 0 95%;" data-width="95%"><section data-role="list" data-width="100%" style="box-sizing:border-box;margin: 0px auto;width: 100%;flex: 0 0 100%;"><section data-role="list"><section data-role="list"><ul class="list-paddingleft-2" style="list-style-type: disc;margin: 0px;padding: 0px 0px 0px 30px;"><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"><span md-inline="plain" style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">一个节点会运行多个 Dramatiq worker processes，即有多个任务同时在执行和打印日志，想要从日志文件中查看某个特定任务的日志会非常困难。此时可以通过 CurrentMessage middleware 获取到当前任务的 message_id，然后结合自定义的 logging Formatter ，在打印的日志添加 message_id 前缀，这样能方便的通过 grep 等命令找到特定任务的所有日志</span><span md-inline="url" spellcheck="false" style="box-sizing: border-box;word-break: break-all;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"></span></span></section></li><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">Dramatiq worker 在 gevent 启动模式下，无法通过 raise exception 来中止执行，因此依赖此的 middleware 如 TimeLimit, Abort 等都无法使用。不过这个问题在 21 年 9 月，有一位大佬提了 PR 解决了这个问题，感兴趣的可以看看 <a href="https://github.com/Flared/dramatiq-abort/issues/11" target="_blank">https://github.com/Flared/dramatiq-abort/issues/11</a></span></section></li></ul></section></section></section></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br/></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;font-size: 15px;letter-spacing: 2px;">聊完开发语言 和 Dramatiq，接下来再介绍一下其他研发流程相关的改进。</span><span style="font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;font-size: 15px;letter-spacing: 2px;">在个人版的容器镜像主要依靠手工构建，在新平台则基于 Gitlab CI/CD，能够在每次代码变更和合并时自动进行构建打包，并推送至容器镜像仓库。</span><span style="font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;font-size: 15px;letter-spacing: 2px;">为了方便功能测试和验证，平台拥有两套配置相同的环境 stg 和 prod，功能需在测试环境上验证通过后才会部署到线上环境。</span><br/></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;font-size: 15px;letter-spacing: 2px;"></span></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;font-size: 15px;letter-spacing: 2px;">此外，在功能上线后，不可避免的会遇到 bug，那么如何知道服务出现了问题？</span><span style="font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;font-size: 15px;letter-spacing: 2px;">这里需要考虑两种场景：</span><br/></section><section data-role="list" style="box-sizing:border-box;color: #3e3e3e;margin: 0px auto;width: 95%;flex: 0 0 95%;" data-width="95%"><section data-role="list" data-width="100%" style="box-sizing:border-box;margin: 0px auto;width: 100%;flex: 0 0 100%;"><section data-role="list"><section data-role="list"><ul class="list-paddingleft-2" style="list-style-type: disc;margin: 0px;padding: 0px 0px 0px 30px;"><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="font-weight: 400;color: rgb(62, 62, 62);text-shadow: none;line-height: 24px;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">代码直接出现报错，如未正确处理异常等。此时可以通过图中的错误监控和追踪服务 Sentry，将错误调用栈等相关信息上报至平台，并发送通知给研发人员进行处理</span></section></li><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="font-weight: 400;color: rgb(62, 62, 62);text-shadow: none;line-height: 24px;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">服务质量，如某功能依赖第三方接口，网络错误、服务不稳定都会导致运行失败。如果每次都打印错误日志，会导致 Sentry 告警太多，无法查看。对于这类问题，有一个共性，即少量的失败是可接受的，只有超过特定比例才会被认为是问题。因此我们需要收集一些指标数据，来监控服务的状态。这部分由图中打点和统计服务 — Prometheus 来完成</span></section></li></ul></section></section></section></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br/></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="letter-spacing: 2px;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">关于平台架构部分，在探索过程中还遇到过其他很多问题，因篇幅关系，此次就先介绍到这里。</span></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br/></section><section style="margin: 0px 8px;padding: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-align: justify;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><section data-mid="t8" mpa-from-tpl="t" style="margin: 20px 0px 0px;padding: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;display: flex;-webkit-box-align: start;align-items: flex-start;-webkit-box-pack: start;justify-content: flex-start;"><section data-preserve-color="t" data-mid="" mpa-from-tpl="t" style="margin: 0px;padding: 0px 30px 0px 2px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;text-align: left;"><section data-preserve-color="t" data-mid="" mpa-from-tpl="t" style="margin: 0px;padding: 0px 30px 5px 2px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;font-size: 14px;color: #000000;border-bottom-width: 2px;border-bottom-style: solid;border-bottom-color: #000000;"><span style="margin: 0px;padding: 0px;max-width: 100%;font-size: 18px;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"><strong style="margin: 0px;padding: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;">0x04. 想法和计划</strong></span></section></section></section></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br/></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="letter-spacing: 2px;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">要想设计出一个好的平台架构，需要不断的尝试和改进，以及大量的时间去打磨优化细节。经过半年多的努力，虽然平台当前架构已经基本成型，但仍然还有很多的不足和优化之处，例如：</span></section><ul class="list-paddingleft-2" cid="n139" mdtype="list" data-mark="-" style="box-sizing: border-box;margin: 0px;padding: 0px 0px 0px 30px;caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-size: 16px;font-weight: normal;text-size-adjust: auto;background-color: rgb(255, 255, 255);text-decoration: none;font-family: &#34;Open Sans&#34;, &#34;Clear Sans&#34;, &#34;Helvetica Neue&#34;, Helvetica, Arial, &#34;Segoe UI Emoji&#34;, sans-serif;"><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">数据库需增加只读实例，以缓解主库压力</span></section></li><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">所有服务共用一个数据库集群，部分非核心服务请求量较大，需要剥离成独立库</span></section></li><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">部分服务的监控缺失或阈值的不合理，需要进一步梳理和调整</span></section></li><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">部分业务日志没有持久化存储，缺少统一查询入口，复杂问题排查较困难</span></section></li><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">随着任务量和存储数据逐步增加，如何更合理的规划未来服务所需资源</span></section></li><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">...</span></section></li></ul><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br/></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;font-size: 15px;letter-spacing: 2px;">对于一个自动化渗透测试平台，良好的架构设计是基础，安全能力则是核心竞争力。</span><span style="font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;font-size: 15px;letter-spacing: 2px;">在过去的半年多，平台的功能基本保持在每周更新上线，目前已经完成近两个大版本的开发，并投入使用。</span><span style="font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;font-size: 15px;letter-spacing: 2px;">对于安全能力，在 2022 年，也将持续投入更多的精力进一步优化和提升效果。</span><br/></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="letter-spacing: 2px;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">不论是提升安全能力还是架构优化，都需要更多的人力投入。因此，下一章节是团队岗位招聘环节，感兴趣的师父可以看看</span></section><section data-role="list" style="box-sizing:border-box;color: #3e3e3e;margin: 0px auto;width: 95%;flex: 0 0 95%;" data-width="95%"><section data-role="list" data-width="100%" style="box-sizing:border-box;margin: 0px auto;width: 100%;flex: 0 0 100%;"><section style="height: 0px;overflow: hidden;line-height: 1.75em;"><br/></section></section></section><section style="margin: 0px 8px;padding: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-align: justify;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><section data-mid="t8" mpa-from-tpl="t" style="margin: 20px 0px 0px;padding: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;display: flex;-webkit-box-align: start;align-items: flex-start;-webkit-box-pack: start;justify-content: flex-start;"><section data-preserve-color="t" data-mid="" mpa-from-tpl="t" style="margin: 0px;padding: 0px 30px 0px 2px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;text-align: left;"><p style="vertical-align:inherit;margin: 0px;padding: 0px 30px 5px 2px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;font-size: 14px;color: #000000;border-bottom-width: 2px;border-bottom-style: solid;border-bottom-color: #000000;"><span style="margin: 0px;padding: 0px;max-width: 100%;font-size: 18px;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"><strong style="margin: 0px;padding: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;">0x05. 岗位招聘</strong></span></p></section></section></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br/></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="letter-spacing: 2px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;font-size: 16px;"><strong style="box-sizing: border-box;caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-size: 16px;orphans: 4;white-space: pre-wrap;text-size-adjust: auto;text-decoration: none;font-family: &#34;Open Sans&#34;, &#34;Clear Sans&#34;, &#34;Helvetica Neue&#34;, Helvetica, Arial, &#34;Segoe UI Emoji&#34;, sans-serif;"><span md-inline="plain" style="font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;font-size: 16px;letter-spacing: 2px;box-sizing: border-box;">团队介绍</span></strong></span></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="letter-spacing: 2px;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">我们是长亭安全服务中心的协同创新团队，团队职责为将一线安全攻防经验，以平台和工具等形式赋能公司各业务，并通过安服业务的实践，快速获取反馈，不断改进和提升安全能力，构筑公司核心竞争力。</span></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="letter-spacing: 2px;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">团队成员包含专业的产品经理、前后端研发、安全开发、攻防专家、运维。技术氛围好，不卷，老板重视。</span></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="letter-spacing: 2px;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">目前团队负责项目包括但不限于：</span></section><ul class="list-paddingleft-2" cid="n161" mdtype="list" data-mark="-" style="box-sizing: border-box;margin: 0px;padding: 0px 0px 0px 30px;caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-size: 16px;font-weight: normal;text-size-adjust: auto;background-color: rgb(255, 255, 255);text-decoration: none;font-family: &#34;Open Sans&#34;, &#34;Clear Sans&#34;, &#34;Helvetica Neue&#34;, Helvetica, Arial, &#34;Segoe UI Emoji&#34;, sans-serif;"><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">自动化渗透测试平台：为一线安服师父打造的持续完善的自动化挖洞”神器“，为安服项目、攻防演练提供支撑</span></section></li><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">攻防知识库平台：集前沿漏洞信息收集、分析、检测、防御的一体化知识库平台，赋能公司全产品线</span></section></li><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">安全实训平台：全方位、一体化的网络安全人才培训平台，在实战中提升企业安全人员的安全素质和技术能力</span></section></li><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">...</span></section></li></ul><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><br/></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="letter-spacing: 2px;font-size: 16px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"><strong style="box-sizing: border-box;caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-size: 16px;orphans: 4;white-space: pre-wrap;text-size-adjust: auto;text-decoration: none;font-family: &#34;Open Sans&#34;, &#34;Clear Sans&#34;, &#34;Helvetica Neue&#34;, Helvetica, Arial, &#34;Segoe UI Emoji&#34;, sans-serif;"><span md-inline="plain" style="font-size: 16px;letter-spacing: 2px;box-sizing: border-box;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">关于岗位</span></strong></span></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="letter-spacing: 2px;box-sizing: border-box;caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-weight: normal;orphans: 4;white-space: pre-wrap;text-size-adjust: auto;text-decoration: none;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">目前招聘的岗位包括：<strong>安全研发、后端研发、红队攻防</strong></span></section><hr style="border-style: solid;border-width: 1px 0 0;border-color: rgba(0,0,0,0.1);-webkit-transform-origin: 0 0;-webkit-transform: scale(1, 0.5);transform-origin: 0 0;transform: scale(1, 0.5);"/><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br/></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"><span style="color: rgb(51, 51, 51);font-size: 15px;orphans: 4;white-space: pre-wrap;caret-color: rgb(51, 51, 51);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">如果你偏好安全，并具备一定的研发能力，可选择 </span><strong style="color: rgb(51, 51, 51);font-size: 15px;orphans: 4;white-space: pre-wrap;caret-color: rgb(51, 51, 51);font-family: &#34;Open Sans&#34;, &#34;Clear Sans&#34;, &#34;Helvetica Neue&#34;, Helvetica, Arial, &#34;Segoe UI Emoji&#34;, sans-serif;">安全研发</strong><span style="color: rgb(51, 51, 51);font-size: 15px;orphans: 4;white-space: pre-wrap;caret-color: rgb(51, 51, 51);font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"> 岗位，工作地点：</span><strong style="color: rgb(51, 51, 51);font-size: 15px;orphans: 4;white-space: pre-wrap;caret-color: rgb(51, 51, 51);font-family: &#34;Open Sans&#34;, &#34;Clear Sans&#34;, &#34;Helvetica Neue&#34;, Helvetica, Arial, &#34;Segoe UI Emoji&#34;, sans-serif;">北京</strong><br/></span></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="color: rgb(51, 51, 51);orphans: 4;white-space: pre-wrap;caret-color: rgb(51, 51, 51);font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">加入我们，你可以：</span></section><ul class="list-paddingleft-2" cid="n174" mdtype="list" data-mark="-" style="box-sizing: border-box;margin: 0px;padding: 0px 0px 0px 30px;caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-size: 16px;font-weight: normal;text-size-adjust: auto;background-color: rgb(255, 255, 255);text-decoration: none;font-family: &#34;Open Sans&#34;, &#34;Clear Sans&#34;, &#34;Helvetica Neue&#34;, Helvetica, Arial, &#34;Segoe UI Emoji&#34;, sans-serif;"><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">参与扫描引擎的开发和优化，包括但不限于服务探测、爬虫、漏洞检测</span></section></li><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">跟进行业新爆发安全漏洞，分析原理，并编写检测 POC</span></section></li><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">学到一线安服和攻击队师父们的渗透思路和经验，并转换为自动化工具</span></section></li><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">...</span></section></li></ul><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-weight: normal;orphans: 4;white-space: pre-wrap;text-size-adjust: auto;text-decoration: none;font-size: 15px;display: inline !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">同时，我们希望你：</span></section><ul class="list-paddingleft-2" cid="n184" mdtype="list" data-mark="-" style="box-sizing: border-box;margin: 0px;padding: 0px 0px 0px 30px;caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-size: 16px;font-weight: normal;text-size-adjust: auto;background-color: rgb(255, 255, 255);text-decoration: none;font-family: &#34;Open Sans&#34;, &#34;Clear Sans&#34;, &#34;Helvetica Neue&#34;, Helvetica, Arial, &#34;Segoe UI Emoji&#34;, sans-serif;"><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">具有扎实的网络基础，掌握任意一门开发语言，具备一定的编程经验</span></section></li><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">熟悉常见安全漏洞原理和检测，了解攻防场景</span></section></li><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">参与过如扫描、爬虫、检测等相关安全产品的研发</span></section></li><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">具有良好的沟通和团队协作能力，热爱技术、责任心强<br/></span></section></li></ul><hr style="border-style: solid;border-width: 1px 0 0;border-color: rgba(0,0,0,0.1);-webkit-transform-origin: 0 0;-webkit-transform: scale(1, 0.5);transform-origin: 0 0;transform: scale(1, 0.5);"/><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br/></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="color: rgb(51, 51, 51);orphans: 4;white-space: pre-wrap;caret-color: rgb(51, 51, 51);font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">如果你偏好研发，可选择 <strong>后端研发</strong> 岗位，工作地点：<strong>北京</strong></span></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="color: rgb(51, 51, 51);orphans: 4;white-space: pre-wrap;caret-color: rgb(51, 51, 51);font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">加入我们，你可以：</span></section><ul class="list-paddingleft-2" cid="n195" mdtype="list" data-mark="-" style="box-sizing: border-box;margin: 0px;padding: 0px 0px 0px 30px;caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-size: 16px;font-weight: normal;text-size-adjust: auto;background-color: rgb(255, 255, 255);text-decoration: none;font-family: &#34;Open Sans&#34;, &#34;Clear Sans&#34;, &#34;Helvetica Neue&#34;, Helvetica, Arial, &#34;Segoe UI Emoji&#34;, sans-serif;"><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">参与分布式、高并发扫描平台的架构设计和优化，学习全栈技术</span></section></li><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">负责模块功能的设计、开发和测试，为公司数百位安全人员提供工具和平台支撑</span></section></li><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">解决全面上云和容器化后所带来的技术挑战，保障平台服务高效稳定运行</span></section></li><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">...</span></section></li></ul><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">同时，我们希望你：</span></section><ul class="list-paddingleft-2" cid="n195" mdtype="list" data-mark="-" style="box-sizing: border-box;margin: 0px;padding: 0px 0px 0px 30px;caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-size: 16px;font-weight: normal;text-size-adjust: auto;background-color: rgb(255, 255, 255);text-decoration: none;font-family: &#34;Open Sans&#34;, &#34;Clear Sans&#34;, &#34;Helvetica Neue&#34;, Helvetica, Arial, &#34;Segoe UI Emoji&#34;, sans-serif;"><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">具有扎实的编程基础和网络基础</span></section></li><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">熟练掌握 python、golang 等任意一门开发语言，追求良好的代码风格</span></section></li><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">具备较强的逻辑思维分析能力和解决问题能力，对解决具有挑战性问题充满激情</span></section></li><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">具有良好的沟通和团队协作能力、热爱技术、责任心强</span></section></li></ul><hr style="border-style: solid;border-width: 1px 0 0;border-color: rgba(0,0,0,0.1);-webkit-transform-origin: 0 0;-webkit-transform: scale(1, 0.5);transform-origin: 0 0;transform: scale(1, 0.5);"/><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br/></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="color: rgb(51, 51, 51);orphans: 4;white-space: pre-wrap;caret-color: rgb(51, 51, 51);font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">如果你偏好攻防实战，可以选择 <strong>红队攻防</strong> 岗位，工作地点：<strong>北京/上海/深圳/广州/成都</strong></span></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="color: rgb(51, 51, 51);orphans: 4;white-space: pre-wrap;caret-color: rgb(51, 51, 51);font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">加入我们，你可以：</span></section><ul class="list-paddingleft-2" cid="n261" mdtype="list" data-mark="-" style="box-sizing: border-box;margin: 0px;padding: 0px 0px 0px 30px;caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-size: 16px;font-weight: normal;text-size-adjust: auto;background-color: rgb(255, 255, 255);text-decoration: none;font-family: &#34;Open Sans&#34;, &#34;Clear Sans&#34;, &#34;Helvetica Neue&#34;, Helvetica, Arial, &#34;Segoe UI Emoji&#34;, sans-serif;"><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">与全国顶尖攻击队师傅一起参与护网/攻防等高端攻击项目，相互学习进步</span></section></li><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">探索研究前沿的攻防技术，并在实战中进行实践验证</span></section></li><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">参与攻击队自动化平台的能力建设，探索和打造顶尖攻击团队</span></section></li><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">...</span><span style="font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;font-size: 15px;"></span></section></li></ul><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0.8em 5px;white-space: pre-wrap;caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-size: 16px;font-weight: normal;background-color: rgb(255, 255, 255);text-decoration: none;font-family: &#34;Open Sans&#34;, &#34;Clear Sans&#34;, &#34;Helvetica Neue&#34;, Helvetica, Arial, &#34;Segoe UI Emoji&#34;, sans-serif;line-height: 1.75em;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">同时，我们希望你：</span></section><ul class="list-paddingleft-2" cid="n269" mdtype="list" data-mark="-" style="box-sizing: border-box;margin: 0px;padding: 0px 0px 0px 30px;caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-size: 16px;font-weight: normal;text-size-adjust: auto;background-color: rgb(255, 255, 255);text-decoration: none;font-family: &#34;Open Sans&#34;, &#34;Clear Sans&#34;, &#34;Helvetica Neue&#34;, Helvetica, Arial, &#34;Segoe UI Emoji&#34;, sans-serif;"><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">具有丰富的实战经验，有大型目标渗透/攻防经验更佳</span></section></li><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">在外网打点/内网横向/域渗透/远控免杀/社工钓鱼/隐蔽持久化/代码审计等一个或多个领域有深入的理解，掌握相关的攻防技术</span></section></li><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">对安全有浓厚的兴趣和较强的独立钻研能力，有良好的团队精神</span></section></li></ul><hr style="border-style: solid;border-width: 1px 0 0;border-color: rgba(0,0,0,0.1);-webkit-transform-origin: 0 0;-webkit-transform: scale(1, 0.5);transform-origin: 0 0;transform: scale(1, 0.5);"/><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><br/></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="letter-spacing: 2px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;font-size: 16px;"><strong style="box-sizing: border-box;caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-size: 16px;orphans: 4;white-space: pre-wrap;text-size-adjust: auto;text-decoration: none;font-family: &#34;Open Sans&#34;, &#34;Clear Sans&#34;, &#34;Helvetica Neue&#34;, Helvetica, Arial, &#34;Segoe UI Emoji&#34;, sans-serif;"><span md-inline="plain" style="font-size: 16px;letter-spacing: 2px;box-sizing: border-box;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">简历投递</span></strong></span></section><ul class="list-paddingleft-2" cid="n216" mdtype="list" data-mark="-" style="box-sizing: border-box;margin: 0px;padding: 0px 0px 0px 30px;caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-size: 16px;font-weight: normal;text-size-adjust: auto;background-color: rgb(255, 255, 255);text-decoration: none;font-family: &#34;Open Sans&#34;, &#34;Clear Sans&#34;, &#34;Helvetica Neue&#34;, Helvetica, Arial, &#34;Segoe UI Emoji&#34;, sans-serif;"><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"><span md-inline="plain" style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">邮箱投递：发送至 </span><span md-inline="url" spellcheck="false" style="box-sizing: border-box;word-break: break-all;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">binlin.yan@chaitin.com</span></span></section></li><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">微信投递：添加微信 xiaobing1024 私聊发送</span></section></li></ul><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="letter-spacing: 2px;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">有岗位问题咨询、技术交流，也可以通过以上方式联系<br/></span></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="letter-spacing: 2px;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"><br/></span></section><section style="margin: 0px 8px;padding: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-align: justify;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><section data-mid="t8" mpa-from-tpl="t" style="margin: 20px 0px 0px;padding: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;display: flex;-webkit-box-align: start;align-items: flex-start;-webkit-box-pack: start;justify-content: flex-start;"><section data-preserve-color="t" data-mid="" mpa-from-tpl="t" style="margin: 0px;padding: 0px 30px 0px 2px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;text-align: left;"><section data-preserve-color="t" data-mid="" mpa-from-tpl="t" style="margin: 0px;padding: 0px 30px 5px 2px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;font-size: 14px;color: #000000;border-bottom-width: 2px;border-bottom-style: solid;border-bottom-color: #000000;"><span style="margin: 0px;padding: 0px;max-width: 100%;font-size: 18px;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"><strong style="margin: 0px;padding: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;">0x06. 总结</strong></span></section></section></section></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br/></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="letter-spacing: 2px;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">在这篇笔记完成时，2021 年已经过去了，在看完远在异国我佳和朋友圈各位师父的年终总结后，觉得自己也该做一个“总结”，因此就有了这篇笔记。文中介绍了我和团队在过去半年多在架构方面的尝试和总结。同第一篇笔记，文字较多，再次感谢大家耐心看完。希望能够为大家提供一些帮助，也希望能够借此机会帮助团队招到更多优秀的小伙伴。</span></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="letter-spacing: 2px;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">最后，因个人能力和水平有限，文中可能会有描述错误或理解不到位的地方，欢迎各位指出和交流。</span></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="letter-spacing: 2px;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">最最后，如果各位觉得文章对你有帮助，欢迎关注、点赞收藏和转发。</span></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br/></section><section style="margin: 0px 8px;padding: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-align: justify;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><section data-mid="t8" mpa-from-tpl="t" style="margin: 20px 0px 0px;padding: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;display: flex;-webkit-box-align: start;align-items: flex-start;-webkit-box-pack: start;justify-content: flex-start;"><section data-preserve-color="t" data-mid="" mpa-from-tpl="t" style="margin: 0px;padding: 0px 30px 0px 2px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;text-align: left;"><section data-preserve-color="t" data-mid="" mpa-from-tpl="t" style="margin: 0px;padding: 0px 30px 5px 2px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;font-size: 14px;color: #000000;border-bottom-width: 2px;border-bottom-style: solid;border-bottom-color: #000000;"><span style="margin: 0px;padding: 0px;max-width: 100%;font-size: 18px;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"><strong style="margin: 0px;padding: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;">0x07. 参考</strong></span></section></section></section></section><section style="vertical-align: inherit;line-height: 1.75em;"><br/></section><ul class="list-paddingleft-2" cid="n228" mdtype="list" data-mark="-" style="box-sizing: border-box;margin: 0px;padding: 0px 0px 0px 30px;caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-size: 16px;font-weight: normal;text-size-adjust: auto;background-color: rgb(255, 255, 255);text-decoration: none;font-family: &#34;Open Sans&#34;, &#34;Clear Sans&#34;, &#34;Helvetica Neue&#34;, Helvetica, Arial, &#34;Segoe UI Emoji&#34;, sans-serif;"><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="font-size: 15px;"><span md-inline="plain" style="box-sizing: border-box;">自动化安全工具平台 - 架构笔记 </span><span md-inline="url" spellcheck="false" style="box-sizing: border-box;word-break: break-all;"><a href="https://mp.weixin.qq.com/s?__biz=MzkwNDE5NzUyMA==&amp;mid=2247483657&amp;idx=1&amp;sn=890bfd44726b334ccaecc5195086aab4&amp;scene=21#wechat_redirect" style="box-sizing: border-box;cursor: pointer;color: #4183c4;-webkit-user-drag: none;font-size: 15px;" data-linktype="2"><a href="https://mp.weixin.qq.com/s/OMhS9yFlcpI9KOQduSxq9g" target="_blank">https://mp.weixin.qq.com/s/OMhS9yFlcpI9KOQduSxq9g</a></a></span></span></section></li><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="font-size: 15px;"><span md-inline="plain" style="box-sizing: border-box;font-size: 15px;">TypeScript </span><span md-inline="url" spellcheck="false" style="box-sizing: border-box;word-break: break-all;font-size: 15px;"><a href="https://www.typescriptlang.org/" target="_blank">https://www.typescriptlang.org/</a></span></span></section></li><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="font-size: 15px;"><span md-inline="plain" style="box-sizing: border-box;font-size: 15px;">gRPC </span><span md-inline="url" spellcheck="false" style="box-sizing: border-box;word-break: break-all;font-size: 15px;"><a href="https://grpc.io/" target="_blank">https://grpc.io/</a></span></span></section></li><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="font-size: 15px;"><span md-inline="plain" style="box-sizing: border-box;font-size: 15px;">Workloads | Kubernetes </span><span md-inline="url" spellcheck="false" style="box-sizing: border-box;word-break: break-all;font-size: 15px;"><a href="https://kubernetes.io/docs/concepts/workloads/" target="_blank">https://kubernetes.io/docs/concepts/workloads/</a></span></span></section></li><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="font-size: 15px;"><span md-inline="plain" style="box-sizing: border-box;font-size: 15px;">Operator pattern | Kubernetes </span><span md-inline="url" spellcheck="false" style="box-sizing: border-box;word-break: break-all;font-size: 15px;"><a href="https://kubernetes.io/docs/concepts/extend-kubernetes/operator/" target="_blank">https://kubernetes.io/docs/concepts/extend-kubernetes/operator/</a></span></span></section></li><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="font-size: 15px;"><span md-inline="plain" style="box-sizing: border-box;font-size: 15px;">The Go Programming Language </span><span md-inline="url" spellcheck="false" style="box-sizing: border-box;word-break: break-all;font-size: 15px;"><a href="https://go.dev/" target="_blank">https://go.dev/</a></span></span></section></li><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="font-size: 15px;"><span md-inline="plain" style="box-sizing: border-box;font-size: 15px;">Dramatiq Cookbook </span><span md-inline="url" spellcheck="false" style="box-sizing: border-box;word-break: break-all;font-size: 15px;"><a href="https://dramatiq.io/cookbook.html" target="_blank">https://dramatiq.io/cookbook.html</a></span></span></section></li><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="font-size: 15px;"><span md-inline="plain" style="box-sizing: border-box;font-size: 15px;">Gitlab CI/CD </span><span md-inline="url" spellcheck="false" style="box-sizing: border-box;word-break: break-all;font-size: 15px;"><a href="https://docs.gitlab.com/ee/ci/" target="_blank">https://docs.gitlab.com/ee/ci/</a></span></span></section></li><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="font-size: 15px;"><span md-inline="plain" style="box-sizing: border-box;font-size: 15px;">Sentry </span><span md-inline="url" spellcheck="false" style="box-sizing: border-box;word-break: break-all;font-size: 15px;"><a href="https://sentry.io/" target="_blank">https://sentry.io/</a></span></span></section></li><li><section style="vertical-align: inherit;box-sizing: border-box;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;line-height: 1.75em;"><span style="font-size: 15px;"><span md-inline="plain" style="box-sizing: border-box;font-size: 15px;">Prometheus </span><span md-inline="url" spellcheck="false" style="box-sizing: border-box;word-break: break-all;font-size: 15px;"><a href="https://prometheus.io/" target="_blank">https://prometheus.io/</a></span></span></section></li></ul><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br/></section><section style="text-align: justify;vertical-align: inherit;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br/></section><section data-role="paragraph"><section style="vertical-align: inherit;line-height: 1.75em;"><br/></section></section></section><section data-role="paragraph"><section style="vertical-align: inherit;line-height: 1.75em;"><br/></section></section><section data-role="paragraph"><section style="vertical-align: inherit;line-height: 1.75em;"><br/></section></section><section data-role="paragraph"><section style="vertical-align: inherit;line-height: 1.75em;"><br/></section></section><section data-role="paragraph"><section style="vertical-align: inherit;line-height: 1.75em;"><br/></section></section><section data-role="paragraph"><section style="vertical-align: inherit;line-height: 1.75em;"><br/></section></section><section data-role="paragraph"><section style="vertical-align: inherit;line-height: 1.75em;"><br/></section></section><section data-role="paragraph"><section style="vertical-align: inherit;line-height: 1.75em;"><br/></section></section><section data-role="paragraph"><section style="vertical-align: inherit;line-height: 1.75em;"><br/></section></section><section data-role="paragraph"><section style="vertical-align: inherit;line-height: 1.75em;"><br/></section></section><section data-role="paragraph"><section style="vertical-align: inherit;line-height: 1.75em;"><br/></section></section><section data-role="paragraph"><section style="vertical-align: inherit;line-height: 1.75em;"><br/></section></section><section data-role="paragraph"><section style="vertical-align: inherit;line-height: 1.75em;"><br/></section></section><section data-role="paragraph"><section style="vertical-align: inherit;line-height: 1.75em;"><br/></section></section><section data-role="paragraph"><section style="vertical-align: inherit;line-height: 1.75em;"><br/></section></section><section data-role="paragraph"><section style="vertical-align: inherit;line-height: 1.75em;"><br/></section></section><section data-role="paragraph"><section style="vertical-align: inherit;line-height: 1.75em;"><br/></section></section><section data-role="paragraph"><section style="vertical-align: inherit;line-height: 1.75em;"><br/></section></section><section data-role="paragraph"><section style="vertical-align: inherit;line-height: 1.75em;"><br/></section></section><section data-role="paragraph"><section style="vertical-align: inherit;line-height: 1.75em;"><br/></section></section><section data-role="paragraph"><section style="vertical-align: inherit;line-height: 1.75em;"><br/></section></section><section data-role="paragraph"><section style="vertical-align: inherit;line-height: 1.75em;"><br/></section></section><section data-role="paragraph"><section style="vertical-align: inherit;line-height: 1.75em;"><br/></section></section><section data-role="paragraph"><section style="vertical-align: inherit;line-height: 1.75em;"><br/></section></section><section data-role="paragraph"><section style="vertical-align: inherit;line-height: 1.75em;"><br/></section></section><section data-role="paragraph"><section style="vertical-align: inherit;line-height: 1.75em;"><br/></section></section><section data-role="paragraph"><section style="vertical-align: inherit;line-height: 1.75em;"><br/></section></section><section data-role="paragraph"><section style="vertical-align: inherit;line-height: 1.75em;"><br/></section></section><section data-role="paragraph"><section style="vertical-align: inherit;line-height: 1.75em;"><br/></section></section><section data-role="paragraph"><section style="vertical-align: inherit;line-height: 1.75em;"><br/></section></section><section data-role="paragraph"><section style="vertical-align: inherit;line-height: 1.75em;"><br/></section></section><section data-role="paragraph"><section style="vertical-align: inherit;line-height: 1.75em;"><br/></section></section><section data-role="paragraph"><section style="vertical-align: inherit;line-height: 1.75em;"><br/></section></section><section data-role="paragraph"><section style="vertical-align: inherit;line-height: 1.75em;"><br/></section></section><section data-role="paragraph"><section style="vertical-align: inherit;line-height: 1.75em;"><br/></section></section></section>



<p><a href="2247483673">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=4e036be5&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzkwNDE5NzUyMA%3D%3D%26mid%3D2247483673%26idx%3D1%26sn%3D88b42a078e291a2f9b3ef8de515731cf%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Wed, 05 Jan 2022 18:14:00 +0800</pubDate>
    </item>
    <item>
      <title>自动化安全工具平台 - 架构笔记</title>
      <link>https://mp.weixin.qq.com/s?__biz=MzkwNDE5NzUyMA==&amp;mid=2247483657&amp;idx=1&amp;sn=890bfd44726b334ccaecc5195086aab4</link>
      <description>个人在自动化安全工具平台架构方面的一些思考、尝试和总结</description>
      <content:encoded><![CDATA[<p>
原创 <span>b1ngz</span> <span>2020-12-24 19:07</span> <span style="display: inline-block;"></span>
</p>

<p>个人在自动化安全工具平台架构方面的一些思考、尝试和总结</p>
<p></p>



<p>
<img src="https://wechat2rss.xlab.app/img-proxy/?k=28cd2377&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F1JicUwKQqRQ55wM3w3dGtfible0uicxQeDqQzibHpTubbnM2DqNet87JB1V6rhicuOJkYgiaI1285QibkylZfp2ib3CYWA%2F0%3Fwx_fmt%3Dpng"/>
</p>


<section label="Edit by 135editor.com" style="font-size: 16px;"><section data-role="outer" label="Powered by 135editor.com" style=""><section style="box-sizing: border-box;padding: 0px;border-style: none;border-width: 2px;border-color: rgb(255, 0, 0);border-radius: 0px;"><section data-role="paragraph"><section style="margin: 0px 8px;padding: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-align: justify;text-size-adjust: auto;text-decoration: none;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"><section style="margin: 0px 8px;padding: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-align: justify;text-size-adjust: auto;text-decoration: none;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"><section data-mid="t8" mpa-from-tpl="t" style="margin: 20px 0px 0px;padding: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;display: flex;-webkit-box-align: start;align-items: flex-start;-webkit-box-pack: start;justify-content: flex-start;"><section data-preserve-color="t" data-mid="" mpa-from-tpl="t" style="margin: 0px;padding: 0px 30px 0px 2px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;text-align: left;"><section data-preserve-color="t" data-mid="" mpa-from-tpl="t" style="margin: 0px;padding: 0px 30px 5px 2px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;font-size: 14px;color: #000000;border-bottom-width: 2px;border-bottom-style: solid;border-bottom-color: #000000;"><span style="margin: 0px;padding: 0px;max-width: 100%;font-size: 18px;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"><strong style="margin: 0px;padding: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;">0x01. 简介</strong></span></section></section></section></section><p style="text-align:justify;margin: 0px 8px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"><br/></p><p style="text-align:justify;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"><span style="letter-spacing: 2px;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">这篇笔记是这几年我在写自动化安全工具平台过程中，在架构方面的一些想法、思考、尝试和总结，主要内容包括：</span></p><section data-role="list" style="box-sizing:border-box;color: #3e3e3e;margin: 0px auto;width: 95%;flex: 0 0 95%;" data-width="95%"><section data-role="list" data-width="100%" style="box-sizing:border-box;margin: 0px auto;width: 100%;flex: 0 0 100%;"><section data-role="list"><section data-role="list" data-width="100%" style="box-sizing:border-box;margin: 0px auto;width: 100%;flex: 0 0 100%;"><ul class="list-paddingleft-2" style="list-style-type: disc;margin: 0px;padding: 0px 0px 0px 30px;"><li><p cid="n965" mdtype="paragraph" dir="ltr" style="text-align:left;max-inline-size: 100%;margin: 0px 0px 0.5rem;padding-left: 0px;box-sizing: border-box;clear: both;white-space: pre-wrap;min-height: 1em;cursor: text;line-height: inherit;orphans: 4;outline: none 0px !important;"><span style="max-inline-size: 100%;margin: 0px;padding: 0px;box-sizing: border-box;cursor: text;font-size: 15px;outline: none 0px !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">为什么我要写自动化安全工具平台？</span></p></li><li><p cid="n967" mdtype="paragraph" dir="ltr" style="text-align:left;max-inline-size: 100%;margin: 0px 0px 0.5rem;padding-left: 0px;box-sizing: border-box;clear: both;white-space: pre-wrap;min-height: 1em;cursor: text;line-height: inherit;orphans: 4;outline: none 0px !important;"><span style="max-inline-size: 100%;margin: 0px;padding: 0px;box-sizing: border-box;cursor: text;font-size: 15px;outline: none 0px !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">平台 1.0 版本架构介绍、所遇到的问题</span></p></li><li><p cid="n969" mdtype="paragraph" dir="ltr" style="text-align:left;max-inline-size: 100%;margin: 0px 0px 0.5rem;padding-left: 0px;box-sizing: border-box;clear: both;white-space: pre-wrap;min-height: 1em;cursor: text;line-height: inherit;orphans: 4;outline: none 0px !important;"><span style="max-inline-size: 100%;margin: 0px;padding: 0px;box-sizing: border-box;cursor: text;font-size: 15px;outline: none 0px !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">平台 2.0 版本架构介绍、如何解决 1.0 版本所遇到的问题</span></p></li><li><p cid="n971" mdtype="paragraph" dir="ltr" style="text-align:left;max-inline-size: 100%;margin: 0px 0px 0.5rem;padding-left: 0px;box-sizing: border-box;clear: both;white-space: pre-wrap;min-height: 1em;cursor: text;line-height: inherit;orphans: 4;outline: none 0px !important;"><span style="max-inline-size: 100%;margin: 0px;padding: 0px;box-sizing: border-box;cursor: text;font-size: 15px;outline: none 0px !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">未来的一些想法和计划</span></p></li><li><p cid="n973" mdtype="paragraph" dir="ltr" style="text-align:left;max-inline-size: 100%;margin: 0px 0px 0.5rem;padding-left: 0px;box-sizing: border-box;clear: both;white-space: pre-wrap;min-height: 1em;cursor: text;line-height: inherit;orphans: 4;outline: none 0px !important;"><span style="max-inline-size: 100%;margin: 0px;padding: 0px;box-sizing: border-box;cursor: text;font-size: 15px;outline: none 0px !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">内容总结</span></p></li></ul></section><p cid="n973" mdtype="paragraph" dir="ltr" style="text-align:left;max-inline-size: 100%;margin: 0px 0px 0.5rem;padding-left: 0px;box-sizing: border-box;clear: both;white-space: pre-wrap;min-height: 1em;cursor: text;line-height: inherit;orphans: 4;outline: none 0px !important;"><span style="max-inline-size: 100%;margin: 0px;padding: 0px;box-sizing: border-box;cursor: text;font-size: 15px;outline: none 0px !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"></span></p></section></section></section></section></section><section style="margin: 0px 8px;padding: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-align: justify;text-size-adjust: auto;text-decoration: none;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"><section data-mid="t8" mpa-from-tpl="t" style="margin: 20px 0px 0px;padding: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;display: flex;-webkit-box-align: start;align-items: flex-start;-webkit-box-pack: start;justify-content: flex-start;"><section data-preserve-color="t" data-mid="" mpa-from-tpl="t" style="margin: 0px;padding: 0px 30px 0px 2px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;text-align: left;"><section data-preserve-color="t" data-mid="" mpa-from-tpl="t" style="margin: 0px;padding: 0px 30px 5px 2px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;font-size: 14px;color: #000000;border-bottom-width: 2px;border-bottom-style: solid;border-bottom-color: #000000;"><span style="margin: 0px;padding: 0px;max-width: 100%;font-size: 18px;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"><strong style="margin: 0px;padding: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;">0x02. Why</strong></span></section></section></section></section><p style="text-align:justify;margin: 0px 8px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"><br/></p><p style="text-align:justify;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"><span style="letter-spacing: 2px;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">在安全测试和挖洞的过程中，我们会用到许多的安全工具，个人在使用时，遇到了如下一些问题：</span></p><section data-role="list" style="box-sizing:border-box;color: #3e3e3e;margin: 0px auto;width: 95%;flex: 0 0 95%;" data-width="95%"><section data-role="list" data-width="100%" style="box-sizing:border-box;margin: 0px auto;width: 100%;flex: 0 0 100%;"><section data-role="list"><section data-role="list"><ul class="list-paddingleft-2" style="list-style-type: disc;margin: 0px;padding: 0px 0px 0px 30px;"><li><p cid="n965" mdtype="paragraph" style="text-align:left;box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">工具的命令行交互方式用户体验不佳，结果查看和筛选不方便</span></p></li><li><p cid="n967" mdtype="paragraph" style="text-align:left;box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">随着工具使用数量增多，需要记住更多的命令和参数，如何有效的打通各工具也成为一个问题</span></p></li><li><p cid="n969" mdtype="paragraph" style="text-align:left;box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">手工操作存在重复劳动，如对于每一个根域名，都要进行子域名收集、IP 解析、端口扫描等操作</span></p></li><li><p cid="n971" mdtype="paragraph" style="text-align:left;box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">结果持久化存储和管理问题，比如我想查询某个域名有哪些子域名、是什么时候发现的、解析到哪些 IP、开放了哪些端口，如果没有资产管理平台，很难实现这些功能</span></p></li><li><p cid="n973" mdtype="paragraph" style="text-align:left;box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">工具开发语言、风格多样化，优化和定制修改成本较高</span></p></li><li><p cid="n973" mdtype="paragraph" style="text-align:left;box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">运行速度，对于大量目标，单机运行的速度远远无法满足需求</span></p></li><li><p cid="n973" mdtype="paragraph" style="text-align:left;box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">工具间缺少公共功能和模块，如定时任务、结果通知</span></p></li><li><p cid="n973" mdtype="paragraph" style="text-align:left;box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">...</span></p></li></ul></section><p cid="n973" mdtype="paragraph" style="text-align:left;box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><br/></p><p cid="n973" mdtype="paragraph" style="text-align:left;box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">因为以上列出和没列出的种种原因，我决定写一个自用的安全工具平台，它需要满足以下条件：</span></p><section data-role="list"><ul class="list-paddingleft-2" style="list-style-type: disc;margin: 0px;padding: 0px 0px 0px 30px;"><li><p cid="n998" mdtype="paragraph" style="box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">提供人性化的 web 管理界面，即能选择的，尽可能不输入，鼠标点击一下能完成的，尽可能不点两下</span></p></li><li><p cid="n1000" mdtype="paragraph" style="box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">将常用工具封装成任务模块，通过参数配置来控制任务执行，实现底层细节屏蔽，简化操作</span></p></li><li><p cid="n1002" mdtype="paragraph" style="box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">实行任务模块间的打通，即某个任务的结果可以作为其他任务的输入</span></p></li><li><p cid="n1004" mdtype="paragraph" style="box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">支持资产管理、任务运行和结果查看等功能</span></p></li><li><p cid="n1006" mdtype="paragraph" style="box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">分布式，可通过机器扩容来提高扫描速率</span></p></li><li><p cid="n1008" mdtype="paragraph" style="box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">支持定时模块，实现任务的自动化周期运行</span></p></li><li><p cid="n1010" mdtype="paragraph" style="box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">...</span></p></li></ul></section><p cid="n973" mdtype="paragraph" style="text-align:left;box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><br/></p><p cid="n973" mdtype="paragraph" style="text-align:left;box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">为了能够实现预期目标，需要有一套良好的架构来支撑，来看一下平台的 1.0 架构</span></p><p cid="n973" mdtype="paragraph" style="text-align:left;box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><br/></p></section></section></section><section style="margin: 0px 8px;padding: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-align: justify;text-size-adjust: auto;text-decoration: none;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"><section data-mid="t8" mpa-from-tpl="t" style="margin: 20px 0px 0px;padding: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;display: flex;-webkit-box-align: start;align-items: flex-start;-webkit-box-pack: start;justify-content: flex-start;"><section data-preserve-color="t" data-mid="" mpa-from-tpl="t" style="margin: 0px;padding: 0px 30px 0px 2px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;text-align: left;"><p style="margin: 0px;padding-left: 2px;max-width: 100%;font-size: 14px;color: #000000;border-bottom: 2px solid #000000;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="margin: 0px;padding: 0px;max-width: 100%;font-size: 18px;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"><strong style="margin: 0px;padding: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;">0x03. 1.0 版本架构</strong></span></p></section></section></section><p style="text-align:justify;margin: 0px 8px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"><br/></p><p style="text-align:justify;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"><span style="letter-spacing: 2px;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">1.0 版本的架构图如下：</span></p><p style="text-align:justify;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"><img data-ratio="0.5771853688778673" data-w="1613" style="box-sizing:border-box;width:&#34;auto&#34;;" src="https://wechat2rss.xlab.app/img-proxy/?k=96382e77&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F1JicUwKQqRQ55wM3w3dGtfible0uicxQeDqTxD2uwhswEheroXV2icq2hKDAiaBuN4M7k0RrIbNF2rMkLVuybu32Jog%2F640"/></p><p style="text-align:justify;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"><span style="letter-spacing: 2px;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">使用到的技术栈和组件信息：</span></p><section data-role="list" style="box-sizing:border-box;color: #3e3e3e;margin: 0px auto;width: 95%;flex: 0 0 95%;" data-width="95%"><section data-role="list" data-width="100%" style="box-sizing:border-box;margin: 0px auto;width: 100%;flex: 0 0 100%;"><section data-role="list"><section data-role="list"><section data-role="list"><section data-role="list"><ul class="list-paddingleft-2" style="list-style-type: disc;margin: 0px;padding: 0px 0px 0px 30px;"><li><p><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">前端：Vue，使用基于 Element UI 的开源管理后台模版</span></p></li><li><p><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"></span><span style="font-size: 15px;orphans: 4;white-space: pre-wrap;caret-color: red;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">后端：Python 3.6，API 使用 </span>Django REST framework</p></li><li><p><span style="font-size: 15px;orphans: 4;white-space: pre-wrap;caret-color: red;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">反向代理：Nginx</span></p></li><li><p><span style="font-size: 15px;orphans: 4;white-space: pre-wrap;caret-color: red;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"></span><span style="orphans: 4;white-space: pre-wrap;caret-color: red;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">数据库：</span>PostgreSQL</p></li><li><p><span style="font-size: 15px;orphans: 4;white-space: pre-wrap;caret-color: red;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">缓存：</span>Redis</p></li><li><p><span style="font-size: 15px;orphans: 4;white-space: pre-wrap;caret-color: red;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">Message Broker：</span>RabbitMQ</p></li><li><p><span style="font-size: 15px;orphans: 4;white-space: pre-wrap;caret-color: red;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">分布式任务框架：</span>Celery</p></li><li><p><span style="font-size: 15px;orphans: 4;white-space: pre-wrap;caret-color: red;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">定时任务：</span>Celery beat</p></li><li><p><span style="font-size: 15px;orphans: 4;white-space: pre-wrap;caret-color: red;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">任务监控：</span>Flower</p></li><li><p><span style="font-size: 15px;orphans: 4;white-space: pre-wrap;caret-color: red;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">服务部署：</span>Docker<span style="font-size: 15px;orphans: 4;white-space: pre-wrap;caret-color: red;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"> + </span>Docker Compose<span style="font-size: 15px;orphans: 4;white-space: pre-wrap;caret-color: red;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"> + SSH</span></p></li></ul></section></section></section></section></section></section><p style="text-align:justify;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"><br/></p><p style="text-align:justify;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"><span style="letter-spacing: 2px;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">对于写过分布式工具的师父来说，整体架构应该还是相对比较简单的。</span></p><p style="text-align:justify;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"><span style="letter-spacing: 2px;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">接着来一起了解一下我是如何选择技术框架和组件的</span></p><section data-role="list" style="box-sizing:border-box;color: #3e3e3e;margin: 0px auto;width: 95%;flex: 0 0 95%;" data-width="95%"><section data-role="list" data-width="100%" style="box-sizing:border-box;margin: 0px auto;width: 100%;flex: 0 0 100%;"><section data-role="list"><section data-role="list"><section data-role="list"><section data-role="list"><section data-role="list"><ul class="list-paddingleft-2" style="list-style-type: disc;margin: 0px;padding: 0px 0px 0px 30px;"><li><p cid="n1023" mdtype="paragraph" style="box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">首先最基础的是开发语言，它决定了后续用到的框架和组件生态。当时用的比较多的开发语言是 Java，但对于写自用的工具而言，Java 在开发效率和成本上都比较 &#34;重&#34; ，因为有很多优秀的开源工具是用 Python 写的，所以最终就选择了它</span></p></li><li><p cid="n1023" mdtype="paragraph" style="box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="font-size: 15px;caret-color: red;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">第二点是前后端框架选型。后端框架上，因为 Django 进行了很多高阶封装，相比轻量级的 Flask 而言，开发速度上会更快。前端框架上，个人认为前后端分离更易于维护，开发效率更高，因此我没有选择 Django 的 templates，也因偶然的机会看到了基于 Vue 的 Element-UI 组件库，试用后觉得这真是像我这种不擅长前端人的福音，之后通过慢慢的学习，也感受到了 Vue 的简洁和强大</span></p></li><li><p cid="n1023" mdtype="paragraph" style="box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="font-size: 15px;caret-color: red;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">第三点是数据库，当时之所以选择了 PostgreSQL，原因有两个，一是想接触一下没有使用过的东西。二是被官网的介绍 - The world&#39;s most advanced open source database 所吸引。在之后的使用过程中，遇到了某些 model 字段需要使用到 JSON 类型，当时 Django 2.x 版本只有 Postgresql 支持。不过在 Django 3.1 版本，主流数据库也都支持了 JSONField，因为是 ORM，只要不是使用到了某个数据库特有的 feature，理论上是可以切换的</span></p></li><li><p cid="n1023" mdtype="paragraph" style="box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="font-size: 15px;caret-color: red;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">第四点是分布式组件，任务调度框架选择了历史悠久、使用广泛、功能全面的 Celery，任务停止、定时任务、任务监控、任务优先级，该有的一应俱全，不过也正因为它悠久的历史，也导致它代码量过于庞大、配置较为复杂，很多  bug 一两年都没有解决，在使用过程中也遇到了一些稳定性方面的问题，导致最终放弃了它，这部分原因后面会具体解释。还有就是 message broker，之前看过一些 RabbitMQ 的文章，稳定、使用广泛，所以就决定是它了</span></p></li><li><p cid="n1023" mdtype="paragraph" style="box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="font-size: 15px;caret-color: red;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"></span><span style="font-size: 15px;caret-color: red;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">最后一点是服务部署，这几年容器化是一个趋势，因此我将平台上所有的服务都基于 docker / docker compose 搭建，容器化能够保证开发和线上环境的一致性，提升服务部署和扩容速度</span></p></li></ul></section></section></section></section></section></section></section><p cid="n965" mdtype="paragraph" style="text-align:left;box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;" dir="ltr"><br/></p><p style="text-align:justify;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"><span style="letter-spacing: 2px;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">了解完技术选型的过程，再来一起看看 1.0 版本在实现和使用过程中，我所遇到的一些问题</span></p><section data-role="list" style="box-sizing:border-box;color: #3e3e3e;margin: 0px auto;width: 95%;flex: 0 0 95%;" data-width="95%"><section data-role="list" data-width="100%" style="box-sizing:border-box;margin: 0px auto;width: 100%;flex: 0 0 100%;"><section data-role="list"><ul class="list-paddingleft-2" style="list-style-type: disc;margin: 0px;padding: 0px 0px 0px 30px;"><li><p cid="n1057" mdtype="paragraph" style="box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">首先第一点是稳定性，安全工具中很多任务都是网络 IO 型，为了提高任务的执行效率，在运行 Celery worker 时是以 Gevent 协程方式启动，在运行一段时间后，会时常出现 BrokenPipeError 错误后 worker 卡死，不再消费队列任务的情况，只能通过重启解决。根据 Github issues 的记录这个问题在 17 年有人报告过，但直到我写这篇笔记时，该问题仍然没有解决，我自己也曾尝试通过阅读源码定位原因，但因为 Celery 代码量较大，最后也放弃了</span></p></li><li><p cid="n1059" mdtype="paragraph" style="box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">第二点是可用性，说到这点，就得提一下 19 年 8 月我发过的一条微博，大致内容是，凌晨收到 VPS 厂商的一封邮件，提示我的一台服务器所在物理机故障，需要重启。早上起来一看，运行任务全部失败，查了下原因，发现那台半夜重启的服务器上运行着 RabbitMQ 服务。然后就在一个月后，我在尝试增加 worker 节点数量，因为没有数据库连接池，高并发导致 worker 频繁的与 db 建立连接，使机器 CPU 飙升到 100%。从这两件事情，我开始思考现在架构在可用性方面的问题，例如是否存在单点故障、是否能够支撑水平无限扩展</span></p></li><li><p cid="n1061" mdtype="paragraph" style="box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">第三点是灵活性和用户体验，实现自动化离不开定时模块，但 1.0 版本的定时任务，无法支持动态创建和修改，需要重启后生效，因此灵活性上需要优化。此外，部分功能前端界面设计的不够友好，管理后台模版功能不够强大，也无法满足极致人性化的要求</span></p></li><li><p cid="n1063" mdtype="paragraph" style="box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">第四点是服务部署和扩容，部分服务仍依赖手工操作。对于自动化部分，配置没有与代码分离开，配置方面也比较复杂，服务上线效率不高</span></p></li><li><p cid="n1065" mdtype="paragraph" style="box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">第五点是代码维护成本，因为 1.0 版本是在边学习边实现的过程中完成的，存在着模块间代码高度耦合、重复代码多等问题，导致代码修改和新功能实现上都较困难。</span></p></li><li><p cid="n1362" mdtype="paragraph" style="box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">...</span></p></li></ul></section></section></section><p style="text-align:justify;margin: 0px 8px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"><br/></p><p style="text-align:justify;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"><span style="letter-spacing: 2px;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">为了解决上述 1.0 版本所面临的问题，实现稳定、高可用、高度自动化的目标，我走上了 2.0 版本的重构和改造之路</span></p><p cid="n998" mdtype="paragraph" style="box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><br/></p><section style="margin: 0px 8px;padding: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-align: justify;text-size-adjust: auto;text-decoration: none;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"><section data-mid="t8" mpa-from-tpl="t" style="margin: 20px 0px 0px;padding: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;display: flex;-webkit-box-align: start;align-items: flex-start;-webkit-box-pack: start;justify-content: flex-start;"><section data-preserve-color="t" data-mid="" mpa-from-tpl="t" style="margin: 0px;padding: 0px 30px 0px 2px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;text-align: left;"><section data-preserve-color="t" data-mid="" mpa-from-tpl="t" style="margin: 0px;padding: 0px 30px 5px 2px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;font-size: 14px;color: #000000;border-bottom-width: 2px;border-bottom-style: solid;border-bottom-color: #000000;"><span style="margin: 0px;padding: 0px;max-width: 100%;font-size: 18px;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"><strong style="margin: 0px;padding: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;">0x04. 2.0 版本架构</strong></span></section></section></section></section><p style="text-align:justify;margin: 0px 8px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"><br/></p><p style="text-align:justify;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"><span style="letter-spacing: 2px;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">2.0 版本的架构图如下</span></p><p style="text-align:justify;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"><span style="letter-spacing: 2px;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"><img data-ratio="0.79177545691906" data-w="1532" style="box-sizing:border-box;width:&#34;auto&#34;;" src="https://wechat2rss.xlab.app/img-proxy/?k=94f897ac&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F1JicUwKQqRQ55wM3w3dGtfible0uicxQeDqFSxFajTXNjlIya3gghUzAxib2g5IZsV6gia93liaO49dwQJGgx18ocS5g%2F640"/></span></p><p style="text-align:justify;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"><span style="color: rgb(62, 62, 62);text-align: justify;caret-color: rgb(62, 62, 62);letter-spacing: 2px;font-size: 15px;display: inline !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">使用到的技术栈和组件信息，这里仅列出与 1.0 版本不同的地方</span></p><section data-role="list" style="box-sizing:border-box;color: #3e3e3e;margin: 0px auto;width: 95%;flex: 0 0 95%;" data-width="95%"><section data-role="list" data-width="100%" style="box-sizing:border-box;margin: 0px auto;width: 100%;flex: 0 0 100%;"><section data-role="list"><ul class="list-paddingleft-2" style="list-style-type: disc;margin: 0px;padding: 0px 0px 0px 30px;"><li><p cid="n1076" mdtype="paragraph" style="box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"><span md-inline="plain" style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">前端：使用更为强大的管理后台模板 </span><span md-inline="url" spellcheck="false" style="box-sizing: border-box;word-break: break-all;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"><a href="https://github.com/PanJiaChen/vue-admin-template" target="_blank">https://github.com/PanJiaChen/vue-admin-template</a></span></span></p></li><li><p cid="n1338" mdtype="paragraph" style="box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">数据库：PostgreSQL Cluster</span></p></li><li><p cid="n1341" mdtype="paragraph" style="box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">数据库连接池：PgBouncer</span></p></li><li><p cid="n1344" mdtype="paragraph" style="box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">Message Broker：RabbitMQ Cluster</span></p></li><li><p cid="n1347" mdtype="paragraph" style="box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">消息监控：RabbitMQ Management Plugin</span></p></li><li><p cid="n1350" mdtype="paragraph" style="box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">分布式任务框架：Dramatiq</span></p></li><li><p cid="n1353" mdtype="paragraph" style="box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">定时任务：APScheduler</span></p></li></ul></section></section></section><p style="text-align:justify;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"><br/></p><p style="text-align:justify;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"><span style="color: rgb(62, 62, 62);text-align: justify;caret-color: rgb(62, 62, 62);letter-spacing: 2px;font-size: 15px;display: inline !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">相比 1.0，新版本改进和优化的地方主要有：</span></p><section data-role="list" style="box-sizing:border-box;color: #3e3e3e;margin: 0px auto;width: 95%;flex: 0 0 95%;" data-width="95%"><section data-role="list" data-width="100%" style="box-sizing:border-box;margin: 0px auto;width: 100%;flex: 0 0 100%;"><section data-role="list"><ul class="list-paddingleft-2" style="list-style-type: disc;margin: 0px;padding: 0px 0px 0px 30px;"><li><p cid="n1087" mdtype="paragraph" style="box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">RabbitMQ 由单节点变为 Cluster 模式，通过 Queue Mirroring 来保证高可用，即某个队列里的消息会在多个节点进行镜像 (mirrored)，即使某个节点异常宕机，消息也不会丢失</span></p></li><li><p cid="n1089" mdtype="paragraph" style="box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">数据库 Postgresql 由单节点变为 Cluster 模式，通过读写分离，增加 slave 节点来支撑 worker 的水平扩展，保证 DB 的稳定性和可用性</span></p></li><li><p cid="n1091" mdtype="paragraph" style="box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">使用 PgBouncer 作为数据库连接池，来避免频繁建立、关闭数据库连接，降低机器负载，提升稳定性</span></p></li><li><p cid="n1093" mdtype="paragraph" style="box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">任务调度框架由 Celery 替换为 Dramatiq，该框架的优点是运行非常稳定、代码结构清晰，但功能上要相比 Celery 少，不过可以通过实现自定义 middleware 来进行扩展</span></p></li><li><p cid="n1095" mdtype="paragraph" style="box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">基于 APScheduler 和 Dramatiq 实现定时任务功能，支持动态添加和修改定时任务</span></p></li><li><p cid="n1178" mdtype="paragraph" style="box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">创建新项目，用于服务的自动化部署，提供修改配置文件的方式，来进行上线和扩容，提高部署效率</span></p></li><li><p cid="n1099" mdtype="paragraph" style="box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">项目重构，将各个任务模块的代码分离，封装公共 utils 函数，提升可维护性</span></p></li><li><p cid="n1101" mdtype="paragraph" style="box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">...</span></p></li></ul></section></section></section><p style="text-align:justify;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"><br/></p><p style="text-align:justify;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"><span style="letter-spacing: 2px;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">除了以上的点外，还有一个关于多任务同时运行，资源分配和抢占的问题，想和大家聊一下</span></p><p style="text-align:justify;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"><span style="letter-spacing: 2px;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">前面提到，任务会通过定时模块周期性的运行，即队列中时时刻刻都有任务在运行或等待运行。假如某天我们发现了一个新漏洞，POC 已写好，扫描任务也已创建，但此时资源都已经被其他已运行的任务占用，只能等待其他任务完成或手动停止释放资源。为了能够更好的解决这个问题，需要有机制能够让新任务具备抢占其他正在运行任务的资源的能力，那么如何实现呢？以下是我的思路和做法：</span></p><section data-role="list" style="box-sizing:border-box;color: #3e3e3e;margin: 0px auto;width: 95%;flex: 0 0 95%;" data-width="95%"><section data-role="list" data-width="100%" style="box-sizing:border-box;margin: 0px auto;width: 100%;flex: 0 0 100%;"><section data-role="list"><ul class="list-paddingleft-2" style="list-style-type: disc;margin: 0px;padding: 0px 0px 0px 30px;"><li><p cid="n1325" mdtype="paragraph" style="box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">队列里的消息/任务需要有优先级之分，即当有空闲资源时，高优先级的任务会优先执行，RabbitMQ 的 Priority Queue 能够很好的支持这一点</span></p></li><li><p cid="n1327" mdtype="paragraph" style="box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">尽量避免一个任务的执行时间过长，即将一个大任务拆分成多个小任务，如每个小任务能够在几分钟内执行完成，这样可以缩短新建高优先级任务等待资源释放的时间</span></p></li><li><p cid="n1329" mdtype="paragraph" style="box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">控制并发执行任务数，假设要扫描几十万 IP 的全端口，我会把它拆分成数量更多的子任务，因为我的机器资源有限，我不会将所有子任务都一次性发送到队列中去，而是会先启动一个端口扫描的主任务，在主任务中来控制子任务的发送。这样做不仅可以实现控制子任务的并发执行数、动态调整优先级、停止任务等功能，还可以动态分配资源，让多个不同优先级的任务能同时运行</span></p></li></ul></section></section></section><p style="text-align:justify;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"><br/></p><p style="text-align:justify;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"><span style="letter-spacing: 2px;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">说了这么多，那么实际效果怎么样呢？以下是 2.0 架构今年的一些使用情况</span></p><section data-role="list" style="box-sizing:border-box;color: #3e3e3e;margin: 0px auto;width: 95%;flex: 0 0 95%;" data-width="95%"><section data-role="list" data-width="100%" style="box-sizing:border-box;margin: 0px auto;width: 100%;flex: 0 0 100%;"><section data-role="list"><ul class="list-paddingleft-2" style="list-style-type: disc;margin: 0px;padding: 0px 0px 0px 30px;"><li><p cid="n1191" mdtype="paragraph" style="box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">未遇到因框架或组件问题导致的服务中断</span></p></li><li><p cid="n1195" mdtype="paragraph" style="box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">最长稳定运行时间 180 天 +，也即我有半年时间没有添加新功能，每天按照配置的定时任务稳定运行的最长记录</span></p></li><li><p cid="n1192" mdtype="paragraph" style="box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">顶峰集群规模：共 84 台服务器，其中 80 台 worker 机器，其余 4 台机器混部 DB、RabbitMQ、Redis 等服务，这个大概跑了两周时间</span></p></li></ul></section></section></section><p style="text-align:justify;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"><br/></p><section style="margin: 0px 8px;padding: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-align: justify;text-size-adjust: auto;text-decoration: none;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"><section data-mid="t8" mpa-from-tpl="t" style="margin: 20px 0px 0px;padding: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;display: flex;-webkit-box-align: start;align-items: flex-start;-webkit-box-pack: start;justify-content: flex-start;"><section data-preserve-color="t" data-mid="" mpa-from-tpl="t" style="margin: 0px;padding: 0px 30px 0px 2px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;text-align: left;"><section data-preserve-color="t" data-mid="" mpa-from-tpl="t" style="margin: 0px;padding: 0px 30px 5px 2px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;font-size: 14px;color: #000000;border-bottom-width: 2px;border-bottom-style: solid;border-bottom-color: #000000;"><span style="margin: 0px;padding: 0px;max-width: 100%;font-size: 18px;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"><strong style="margin: 0px;padding: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;">0x05. 想法和计划</strong></span></section></section></section></section><p style="text-align:justify;margin: 0px 8px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"><br/></p><p style="text-align:justify;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"><span style="letter-spacing: 2px;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">虽然 2.0 版本优化和解决了 1.0 版本中的很多问题，但它仍然有很多不足和待改进的地方，例如数据库使用集群模式后，存在多个节点，目前 worker 端连接时，是随机选择其一，一旦某个节点宕机，就会导致部分请求失败，再加上数据库配置是通过 docker env-file 传入，无法实现动态摘除节点，需要重新部署。另外，随机选择也带了另一个问题，不同节点之间的负载存在不均衡的情况。因此，为了能够让平台更加稳定，实现高度自动化目标，还需要对架构进行进一步的优化。以下是目前的一些 ToDo，因为只是初步的想法，有可能不一定会实际去实现，大家可以简单参考一下：</span></p><section data-role="list" style="box-sizing:border-box;color: #3e3e3e;margin: 0px auto;width: 95%;flex: 0 0 95%;" data-width="95%"><section data-role="list" data-width="100%" style="box-sizing:border-box;margin: 0px auto;width: 100%;flex: 0 0 100%;"><section data-role="list"><ul class="list-paddingleft-2" style="list-style-type: disc;margin: 0px;padding: 0px 0px 0px 30px;"><li><p cid="n965" mdtype="paragraph" style="text-align:left;box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;" dir="ltr"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">基于如 ZooKeeper 或 etcd 实现统一分布式配置中心，解决数据库、RabbitMQ 等配置的动态更新问题</span></p></li><li><p cid="n967" mdtype="paragraph" style="text-align:left;box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;" dir="ltr"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">基于如 HAProxy 实现 TCP 代理，解决数据库、RabbitMQ 等服务高可用和负载均衡问题</span></p></li><li><p cid="n969" mdtype="paragraph" style="text-align:left;box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;" dir="ltr"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">继续完善和提高服务自动化部署程度，例如自动化扩容数据库 Slaver 节点、RabbitMQ 节点等</span></p></li><li><p cid="n971" mdtype="paragraph" style="text-align:left;box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;" dir="ltr"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">完善服务监控和报警功能，如接入 Sentry 等</span></p></li><li><p cid="n973" mdtype="paragraph" style="text-align:left;box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;" dir="ltr"><span style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">...</span></p></li></ul></section></section></section><section style="margin: 0px 8px;padding: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-align: justify;text-size-adjust: auto;text-decoration: none;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"><section data-mid="t8" mpa-from-tpl="t" style="margin: 20px 0px 0px;padding: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;display: flex;-webkit-box-align: start;align-items: flex-start;-webkit-box-pack: start;justify-content: flex-start;"><section data-preserve-color="t" data-mid="" mpa-from-tpl="t" style="margin: 0px;padding: 0px 30px 0px 2px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;text-align: left;"><section data-preserve-color="t" data-mid="" mpa-from-tpl="t" style="margin: 0px;padding: 0px 30px 5px 2px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;font-size: 14px;color: #000000;border-bottom-width: 2px;border-bottom-style: solid;border-bottom-color: #000000;"><span style="margin: 0px;padding: 0px;max-width: 100%;font-size: 18px;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"><strong style="margin: 0px;padding: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;">0x06. 总结</strong></span></section></section></section></section><p style="text-align:justify;margin: 0px 8px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"><br/></p><p style="text-align:justify;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"><span style="letter-spacing: 2px;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">这篇笔记介绍了我在写自动化安全工具平台过程中，在构架方面的一些个人思考和总结，文字比较多，感谢大家耐心看完，希望能够给同样在写自动化工具的人提供一些帮助。另外，因个人能力和水平有限，文中可能会有描述错误或理解不到位的地方，欢迎各位指正和交流。</span></p><p style="text-align:justify;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"><span style="letter-spacing: 2px;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">最后是下篇笔记的预告时间，我会介绍平台上的一些功能和自己的想法，感兴趣的老板可以关注一下</span></p><section style="margin: 0px 8px;padding: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-align: justify;text-size-adjust: auto;text-decoration: none;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"><section data-mid="t8" mpa-from-tpl="t" style="margin: 20px 0px 0px;padding: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;display: flex;-webkit-box-align: start;align-items: flex-start;-webkit-box-pack: start;justify-content: flex-start;"><section data-preserve-color="t" data-mid="" mpa-from-tpl="t" style="margin: 0px;padding: 0px 30px 0px 2px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;text-align: left;"><section data-preserve-color="t" data-mid="" mpa-from-tpl="t" style="margin: 0px;padding: 0px 30px 5px 2px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;font-size: 14px;color: #000000;border-bottom-width: 2px;border-bottom-style: solid;border-bottom-color: #000000;"><span style="margin: 0px;padding: 0px;max-width: 100%;font-size: 18px;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"><strong style="margin: 0px;padding: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;">0x07. 参考</strong></span></section></section></section></section><p style="text-align:justify;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"><br/></p><section data-role="list" style="box-sizing:border-box;color: #3e3e3e;margin: 0px auto;width: 95%;flex: 0 0 95%;" data-width="95%"><section data-role="list" data-width="100%" style="box-sizing:border-box;margin: 0px auto;width: 100%;flex: 0 0 100%;"><section data-role="list"><section data-role="list" data-width="100%" style="box-sizing:border-box;margin: 0px auto;width: 100%;flex: 0 0 100%;"><section data-role="list"><ul class="list-paddingleft-2" style="list-style-type: disc;margin: 0px;padding: 0px 0px 0px 30px;"><li><p cid="n2456" mdtype="paragraph" style="box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"><span md-inline="plain" style="font-size: 15px;box-sizing: border-box;">Django REST framework </span><span md-inline="url" spellcheck="false" style="font-size: 15px;box-sizing: border-box;word-break: break-all;"><a href="https://www.django-rest-framework.org/" target="_blank">https://www.django-rest-framework.org/</a></span></span></p></li><li><p cid="n2450" mdtype="paragraph" style="box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"><span md-inline="plain" style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">Dramatiq: background tasks  </span><span md-inline="url" spellcheck="false" style="box-sizing: border-box;word-break: break-all;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"><a href="https://dramatiq.io/" target="_blank">https://dramatiq.io/</a></span></span></p></li><li><p cid="n2428" mdtype="paragraph" style="box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"><span md-inline="plain" style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">Clustering Guide — RabbitMQ </span><span md-inline="url" spellcheck="false" style="box-sizing: border-box;word-break: break-all;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"><a href="https://www.rabbitmq.com/clustering.html" target="_blank">https://www.rabbitmq.com/clustering.html</a></span></span></p></li><li><p cid="n2441" mdtype="paragraph" style="box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"><span md-inline="plain" style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">Priority Queue Support — RabbitMQ </span><span md-inline="url" spellcheck="false" style="box-sizing: border-box;word-break: break-all;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"><a href="https://www.rabbitmq.com/priority.html" target="_blank">https://www.rabbitmq.com/priority.html</a></span></span></p></li><li><p cid="n2437" mdtype="paragraph" style="box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"><span md-inline="plain" style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">PostgreSQL High Availability, Load Balancing, and Replication </span><span md-inline="url" spellcheck="false" style="box-sizing: border-box;word-break: break-all;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"><a href="https://www.postgresql.org/docs/11/high-availability.html" target="_blank">https://www.postgresql.org/docs/11/high-availability.html</a></span></span></p></li><li><p cid="n2479" mdtype="paragraph" style="box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"><span md-inline="plain" style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">PgBouncer - lightweight connection pooler for PostgreSQL </span><span md-inline="url" spellcheck="false" style="box-sizing: border-box;word-break: break-all;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"><a href="https://www.pgbouncer.org/" target="_blank">https://www.pgbouncer.org/</a></span></span></p></li><li><p cid="n2461" mdtype="paragraph" style="box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"><span md-inline="plain" style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">Celery </span><span md-inline="url" spellcheck="false" style="box-sizing: border-box;word-break: break-all;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"><a href="https://docs.celeryproject.org/en/stable/getting-started/introduction.html" target="_blank">https://docs.celeryproject.org/en/stable/getting-started/introduction.html</a></span></span></p></li><li><p cid="n2464" mdtype="paragraph" style="box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"><span md-inline="plain" style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">Vue.js </span><span md-inline="url" spellcheck="false" style="box-sizing: border-box;word-break: break-all;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"><a href="https://vuejs.org/" target="_blank">https://vuejs.org/</a></span></span></p></li><li><p cid="n2467" mdtype="paragraph" style="box-sizing: border-box;line-height: inherit;orphans: 4;margin: 0px 0px 0.5rem;white-space: pre-wrap;"><span style="font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"><span md-inline="plain" style="box-sizing: border-box;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;">Element - A Desktop UI Toolkit for Web </span><span md-inline="url" spellcheck="false" style="box-sizing: border-box;word-break: break-all;font-size: 15px;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Apple Color Emoji&#34;, &#34;Emoji Symbols Font&#34;, &#34;Segoe UI Symbol&#34;, Arial, sans-serif;"><a href="https://element.eleme.io/" target="_blank">https://element.eleme.io/</a></span></span></p></li></ul></section></section><p cid="n973" mdtype="paragraph" dir="ltr" style="text-align:left;max-inline-size: 100%;margin: 0px 0px 0.5rem;padding-left: 0px;box-sizing: border-box;clear: both;white-space: pre-wrap;min-height: 1em;cursor: text;line-height: inherit;orphans: 4;outline: none 0px !important;"><br/></p></section></section></section><p style="text-align:justify;margin: 0px 8px 10px;padding-left: 0px;max-width: 100%;caret-color: rgb(62, 62, 62);color: rgb(62, 62, 62);font-size: 16px;font-weight: normal;text-size-adjust: auto;text-decoration: none;line-height: 1.75em;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: &#34;Helvetica Neue&#34;, Helvetica, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;"><br/></p></section><section data-role="paragraph"><p><br/></p></section></section></section>



<p><a href="2247483657">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=5338af73&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzkwNDE5NzUyMA%3D%3D%26mid%3D2247483657%26idx%3D1%26sn%3D890bfd44726b334ccaecc5195086aab4%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Thu, 24 Dec 2020 19:07:00 +0800</pubDate>
    </item>
  </channel>
</rss>