{"componentChunkName":"component---src-templates-best-practice-detail-tsx","path":"/best-practice/2020-09-28-weibao","result":{"data":{"currentBlog":{"id":"4af7123d-e5b7-5c3d-9c99-d85c35c84898","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/2020930/1601452545995-1601451648554-%E5%BE%AE%E4%BF%9Djpg.jpg","authors":["Weibao"],"categories":["best-practice"],"date":"2020-09-28T00:00:00.000Z","title":"微保的 Serverless 云函数实践之路","description":"微保 Serverless 实践之架构演进","authorslink":null,"translators":null,"translatorslink":null,"tags":["Serverless","架构设计"],"keywords":"Serverless Framework,Serverless,SCF","outdated":null},"wordCount":{"words":369,"sentences":79,"paragraphs":79},"fileAbsolutePath":"/opt/build/repo/content/best-practice/2020-09-28-weibao.md","fields":{"slug":"/best-practice/2020-09-28-weibao/","keywords":["serverless","云函数","函数","日志","架构","Serverless","团队","业务","中间层","serverlesscloud","微保"]},"html":"<p><img src=\"https://img.serverlesscloud.cn/2020928/1601285206848-00.jpg\">      </p>\n<h2 id=\"背景\"><a href=\"#%E8%83%8C%E6%99%AF\" aria-label=\"背景 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>背景</h2>\n<p>微保前端架构在业务发展中，根据业务、团队、开发等实际情况，不断进化调整。本文将具体介绍微保前端的架构演进过程，以及团队最终选择使用腾讯云 Serverless 技术支撑前端架构的原因。</p>\n<p>微保团队使用 Serverless 技术的主要应用场景：</p>\n<ol>\n<li>前端开发同学，应用在BFF层，目前接入的有小程序，H5 页面。</li>\n<li>数据组同学，面向的风控和推荐算法应用，做计算使用。</li>\n</ol>\n<h2 id=\"微保架构-v1\"><a href=\"#%E5%BE%AE%E4%BF%9D%E6%9E%B6%E6%9E%84-v1\" aria-label=\"微保架构 v1 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>微保架构 v1</h2>\n<p>早期，团队使用经典的前后分离架构，前端开发与后端开发通过接口进行合作。</p>\n<p>合作流程如下图所示：</p>\n<p><img src=\"https://img.serverlesscloud.cn/2020928/1601285210728-01.jpg\">            </p>\n<p>毫无疑问，前后端分离的架构有比较显著的优势：</p>\n<p><strong>1. 前后端开发解耦</strong></p>\n<ul>\n<li>前端与后端开发并行，缩短需求整体开发周期</li>\n</ul>\n<p><img src=\"https://img.serverlesscloud.cn/2020928/1601285212842-02.jpg\">            </p>\n<ul>\n<li>角色分工明确，线上问题定位与修复更加清晰</li>\n</ul>\n<p>前后端分别设计与实现自己的错误监控和告警系统，前端对页面脚本错误进行捕获，上报至日志平台，经过日志处理工具，设置告警机制，将错误信息推送至相应的开发人员。</p>\n<ul>\n<li>利于前端组件化与后端微服务化架构</li>\n</ul>\n<p>前后端分离后，前端可以使用更为便捷的框架以及基于这些框架的基础UI组件，大大提升开发效率。另外，前端开发也会基于业务的特点，提取业务专属的公共组件，所有组件化的沉淀，都是对生产效率的提升。</p>\n<p><strong>2. 部署解耦</strong></p>\n<ul>\n<li>前端静态文件单独部署 CDN</li>\n</ul>\n<p>前端项目中有大量的静态文件，包括 html、css、js、图片、视频等，将这些文件部署在 CDN 上，充分利用现有云服务的CDN能力，既能提升资源访问的速度又能保证资源访问的稳定性，尤其是在高并发的场景下。</p>\n<ul>\n<li>更加快捷的 CI/CD ，前端的编译过程可以非常简单地接入 CI/CD</li>\n</ul>\n<p>在前后端耦合的时代，前后端的统一部署相互依赖，分开部署后，可以针对前端项目以gitlab的repo 级别来做相应的 CI/CD。</p>\n<p><strong>然而，</strong> 前后分离的架构对于业务早期的快速发展非常有效，而且在团队规模较小的时候，前后端开发人员合作固定，彼此对于对方的开发习惯、性格较熟，因此跨角色沟通的问题并不突出。但随着团队规模和业务规模持续扩大，这个架构模式给团队带来的副作用慢慢浮出水面。实践中，遇到的几个比较明显的问题，如下：</p>\n<p><strong>1. 前后端协作耦合慢慢成为开发效率提升的瓶颈。</strong></p>\n<p>如下图所示：</p>\n<p><img src=\"https://img.serverlesscloud.cn/2020928/1601285216810-03.jpg\">            </p>\n<p>团队规模与业务规模的扩大，意味着合作的人员变多、接口的复杂度也会相应增加。</p>\n<p>早期专人专项大家彼此的开发习惯也熟悉，对业务也都比较熟悉，因此业务接口参数的调整沟通成本较低。但随着业务规模和团队成员扩充，在各种跨业务合作时就会有人碰到不习惯阅读proto，或有些复杂业务需要花费大量时间阅读proto文档，或前后端反复沟通接口调用时参数的具体含义等问题。</p>\n<p><strong>2. 页面渲染效率较差</strong></p>\n<p>如下图所示</p>\n<p><img src=\"https://img.serverlesscloud.cn/2020928/1601285219013-04.jpg\">            </p>\n<p>以产品详情页为例，页面的渲染需要请求至少5个后端接口，然后再对数据进行组装和处理。这不仅增加了小程序端的代码体积，页面渲染的速度也是被拉低了。</p>\n<p>即使在前端页面对接口进行并行访问，但数据的整合逻辑依然会非常复杂。小程序作为微保主要的产品承载形态，代码量巨大，几近达到微信规定的代码上限，这种对于代码的增加随着业务增长也是一个隐形的风险。</p>\n<h2 id=\"微保架构-v2\"><a href=\"#%E5%BE%AE%E4%BF%9D%E6%9E%B6%E6%9E%84-v2\" aria-label=\"微保架构 v2 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>微保架构 v2</h2>\n<p>鉴于上述前后端合作模式中的痛点，团队对架构再次进行优化，原则是业务“前”移、核心下沉。在前期的各种业务支撑中，团队已经有了一些业务中台的沉淀，比如投保服务、续保服务、保单服务等。</p>\n<p>中间层的引入让团队的开发效率进一步得到提升，前端对于业务的把控力及页面性能优化的操作空间也大大加强。不管是从团队的敏捷性、还是应用的体验，都有不错的改善，比如以下几个方面：</p>\n<p><strong>1. 前后端流程上的耦合大大减小，角色责任的专一性逐步形成</strong></p>\n<p>基于一部分后端服务能力的积累，比如保单相关的需求，在需求评审及开发过程中，只需要前端开发同学参加即可。前端开发同学与业务产品沟通业务逻辑，在api市场或服务文档查询相应的服务能力，完成业务开发。同时对于团队逐步开展业务中台化、前端组件化大有助益，整个架构对于丰富多变的业务需求的响应更敏捷。</p>\n<p>2<strong>. 渲染层对后端的服务进行聚合，减少页面请求</strong></p>\n<p><img src=\"https://img.serverlesscloud.cn/2020928/1601285222648-05.jpg\">            </p>\n<p>不管是H5网页还是小程序页面，均只需跟中间层打交道，前端开发人员根据业务的诉求，自行对接口进行聚合，端上只需要1个请求就可以开始渲染页面。接口聚合之前，产品详情页面的显示需要请求5个接口，平均的接口请求耗时为120ms左右，聚合后，通过中间层来请求5个内网接口，避免端与服务的多次连接耗时。</p>\n<p><strong>3. 中间层对数据进行加工，大大减少小程序端的逻辑代码量</strong></p>\n<p>之前在小程序端的数据整合代码，有些复杂的逻辑，可以交给中间层处理，这些代码的节省对于业务持续增长时会越来越体现出价值。以年金产品详情页为例，数据在中间层聚合能够节省10KB的体积。</p>\n<p>中间层的引入是对生产力的进一步解放，但基于一个巨型 app 的 node 中间层，在后期的运维中也暴露出一些问题。中间层的应用部署在2台CVM机器上，有其先天的一些不足：</p>\n<p><strong>1. 应对尖峰流量的冲击能力差</strong></p>\n<p>微保经常会有一些运营和投放需求，这些事件都会导致瞬间的大流量打入，CVM的扩容相对滞后。</p>\n<p><strong>2. App级别的部署与发布</strong></p>\n<p>中间层不断积累业务代码，整个应用线性增长，每次部署与发布都是巨石应用的发布，部署效率低、风险高。</p>\n<p><strong>3. 前端开发人员在开发、测试环境中需要自己在机器上查阅日志和服务操作，提高了普及的门槛。</strong></p>\n<h2 id=\"微保架构-v3\"><a href=\"#%E5%BE%AE%E4%BF%9D%E6%9E%B6%E6%9E%84-v3\" aria-label=\"微保架构 v3 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>微保架构 v3</h2>\n<p>基于上面的这些限制，团队开始关注新的技术，加州大学伯克利分校计算机科学 Riselab 团队的实验室研究室提出：Serverless 是云计算的下一个浪潮。国内各大厂商也都开始布局 Serverless ，腾讯云 Serverless 团队是国内比较早在这方面进行部署的团队，技术已经非常成熟，在新东方、蘑菇街、哔哩哔哩、TP-link 等数百家企业成功落地实践。</p>\n<p>通过调研了解到腾讯云 Serverless 云函数的优势：</p>\n<ul>\n<li>强大的扩所容能力，特别适合应对流量洪峰，且性能稳定。</li>\n<li>每个函数都是单独运行、单独部署、单独伸缩的，用户上传代码后即可自动部署，提升了独立开发和迭代的速度。</li>\n<li>云函数提供精细的日志记录，可方便地查看函数的运行状况，并对代码进行调试、测试和审计；支持相关的监控指标上报，能快速了解函数的整体运行概况，也可自定义云函数的监控指标。</li>\n<li>精确到 1ms 计费规则，只对正在运行的函数计费。</li>\n</ul>\n<p>综上，基本解决了架构 v2 中面临的问题，可以说是省时省力。经过团队整体评估，我们决定使用腾讯云 Serverless 云函数进行架构的进一步调整。调整后的角色合作流程示意图，如下：</p>\n<p><img src=\"https://img.serverlesscloud.cn/2020928/1601285231734-06.jpg\">            </p>\n<p>C 端的请求发至云函数 API 网关，网关转发请求至相应的云函数实例，云函数再向后请求服务的网关。整个链条上最大的变化是将云函数取代了node app，成为中间层的技术形态。</p>\n<p>使用云函数替换掉 node app，背后的考量有以下几方面，也基本是针对 node app 实践中遇到的一些问题去加以解决：</p>\n<p><strong>1. 自动扩缩容</strong></p>\n<p>开发者不需要专门去配置，云函数可以自己根据请求量在函数层级水平扩展，正常情况下，一个空的云函数（运行时间 50 ms），300 个并发，压测可以达到 6000+ 的 qps，应对日常的高并发需求基本没什么问题。</p>\n<p><strong>2. 函数级别的开发与部署</strong></p>\n<p>一个云函数对应一个 gitlab 的项目，函数开发与发布都是围绕单个项目进行 CI/CD，高效、安全。</p>\n<p><strong>3. 按需收费</strong></p>\n<p>对于金融模式下的流量特点，大部分情况下请求量较少，云函数的使用可以避免稳定的资源投入，空闲情况下费用大大减少。</p>\n<p><strong>4. 简单的运维管理</strong></p>\n<p>开发者不需要在服务器上自己维护服务和查阅日志，通过云函数的配套工具轻松管理函数、查阅日志，也可以根据自己的诉求设置告警机制。</p>\n<h2 id=\"微保使用-serverless-技术的总体架构\"><a href=\"#%E5%BE%AE%E4%BF%9D%E4%BD%BF%E7%94%A8-serverless-%E6%8A%80%E6%9C%AF%E7%9A%84%E6%80%BB%E4%BD%93%E6%9E%B6%E6%9E%84\" aria-label=\"微保使用 serverless 技术的总体架构 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>微保使用 Serverless 技术的总体架构</h2>\n<p>微保每一次架构的调整，都致力于让各种研发角色的职责更为单一、内聚，角色间更加解耦。但这种调整也需要有配套的工具，其中的 trade-off 需要根据短期成本和长期利益来衡量。腾讯云Servelrss 云函数很好的支持了本次架构的重新调整。</p>\n<p><img src=\"https://img.serverlesscloud.cn/2020928/1601285234546-07.jpg\">            </p>\n<h2 id=\"落地中的问题和解决办法\"><a href=\"#%E8%90%BD%E5%9C%B0%E4%B8%AD%E7%9A%84%E9%97%AE%E9%A2%98%E5%92%8C%E8%A7%A3%E5%86%B3%E5%8A%9E%E6%B3%95\" aria-label=\"落地中的问题和解决办法 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>落地中的问题和解决办法</h2>\n<p>使用腾讯云 Serverless 过程中也不免遇到问题。</p>\n<p>例如，公司有自建 es 集群，所有日志都会放在es里面，但是云函数的日志无法直接放入我们es里面，只能存入腾讯云的 cls，这个对于我们后期日志分析， 告警都不好处理。通过调研腾讯云cls， 发现里面有个挺好用的功能，可以日志投递到 kafka，在通过监听 kafka，我们将日志成功存入我们的 es, 且时延保证在秒级。</p>\n<p>另一个日志规范问题, 日志的规范关乎后期日志分析、告警， 但是实际处理中发现日志的元数据信息较少， 比如我们有版本 tag，云函数绑定了 cmdb 相关信息，这些都希望在日志中打印出来, 后面我们发现云函数有个别名字段。我们在云函数中发现一个别名字段, 通过扩展了一下这个字段，填入了更多信息， 例如版本、cmdb 相关信息，这样在日志里面相关信息也会体现出来。</p>\n<p>关于使用腾讯云 Serverless 技术在风控和推荐算法应用的介绍会在之后的文章为大家详细展开，敬请期待！</p>\n<hr>\n<hr>\n<div id='scf-deploy-iframe-or-md'></div>\n<hr>\n<p>欢迎访问：<a href=\"https://serverlesscloud.cn/\">Serverless 中文网</a>，您可以在 <a href=\"https://serverlesscloud.cn/best-practice\">最佳实践</a> 里体验更多关于 Serverless 应用的开发！</p>","tableOfContents":"<ul>\n<li><a href=\"/best-practice/2020-09-28-weibao/#%E8%83%8C%E6%99%AF\">背景</a></li>\n<li><a href=\"/best-practice/2020-09-28-weibao/#%E5%BE%AE%E4%BF%9D%E6%9E%B6%E6%9E%84-v1\">微保架构 v1</a></li>\n<li><a href=\"/best-practice/2020-09-28-weibao/#%E5%BE%AE%E4%BF%9D%E6%9E%B6%E6%9E%84-v2\">微保架构 v2</a></li>\n<li><a href=\"/best-practice/2020-09-28-weibao/#%E5%BE%AE%E4%BF%9D%E6%9E%B6%E6%9E%84-v3\">微保架构 v3</a></li>\n<li><a href=\"/best-practice/2020-09-28-weibao/#%E5%BE%AE%E4%BF%9D%E4%BD%BF%E7%94%A8-serverless-%E6%8A%80%E6%9C%AF%E7%9A%84%E6%80%BB%E4%BD%93%E6%9E%B6%E6%9E%84\">微保使用 Serverless 技术的总体架构</a></li>\n<li><a href=\"/best-practice/2020-09-28-weibao/#%E8%90%BD%E5%9C%B0%E4%B8%AD%E7%9A%84%E9%97%AE%E9%A2%98%E5%92%8C%E8%A7%A3%E5%86%B3%E5%8A%9E%E6%B3%95\">落地中的问题和解决办法</a></li>\n</ul>"},"previousBlog":{"id":"7095aff6-92f7-584e-9803-b6f1db15e4f4","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/20201012/1602475343467-1602323330220-%E4%B8%A4%E8%A1%8C_%E8%93%9D%E8%89%B2s.jpg","authors":["LuckyYo"],"categories":["best-practice"],"date":"2020-10-12T00:00:00.000Z","title":"Labelhub 基于腾讯云 Serverless 技术为人工智能企业提供数据与模型解决方案","description":"轻松构建数据可视化运维面板实践分享","authorslink":null,"translators":null,"translatorslink":null,"tags":["Serverless","人工智能"],"keywords":"Serverless Framework,Serverless,SCF,labelhub,人工智能","outdated":null},"wordCount":{"words":289,"sentences":59,"paragraphs":59},"fileAbsolutePath":"/opt/build/repo/content/best-practice/2020-10-12-labelhub.md","fields":{"slug":"/best-practice/2020-10-12-labelhub/","keywords":["go","python","rest api","serverless","云函数","Serverless","函数","组件","部署","user","bash","配置文件","labelhub","common"]}},"nextBlog":{"id":"a68be5c7-9013-5f9b-a4d7-df0a149c8326","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/202099/1599650772819-1599646529564-%E8%98%91%E8%8F%87%E8%A1%97.jpg","authors":["Tianyun"],"categories":["best-practice"],"date":"2020-09-09T00:00:00.000Z","title":"腾讯云 Serverless ETL —— 蘑菇街实战落地","description":"轻量、快速、灵活、省心、低成本的 Serverless 通用数据处理解决方案！","authorslink":null,"translators":null,"translatorslink":null,"tags":["Serverless","ETL"],"keywords":"Serverless, Serverless ETL","outdated":null},"wordCount":{"words":355,"sentences":68,"paragraphs":68},"fileAbsolutePath":"/opt/build/repo/content/best-practice/2020-09-09-serverless-etl.md","fields":{"slug":"/best-practice/2020-09-09-serverless-etl/","keywords":["serverless","云函数","函数","serverlesscloud","Ckafka","Serverless","腾讯"]}}},"pageContext":{"isCreatedByStatefulCreatePages":false,"blogId":"4af7123d-e5b7-5c3d-9c99-d85c35c84898","previousBlogId":"7095aff6-92f7-584e-9803-b6f1db15e4f4","nextBlogId":"a68be5c7-9013-5f9b-a4d7-df0a149c8326"}}}