<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>flydragon (flydragon)</title>
    <link>https://ruby-china.org/flydragon</link>
    <description></description>
    <language>en-us</language>
    <item>
      <title>[绍兴柯桥 / 杭州萧山] 有数派 诚聘 Ruby 后端 / 长期有效 ( 15K - 30K )</title>
      <description>&lt;h2 id="什么是有数派 ？"&gt;什么是有数派？&lt;/h2&gt;
&lt;p&gt;有数派  ( &lt;a href="https://youshupai.com" rel="nofollow" target="_blank"&gt;https://youshupai.com&lt;/a&gt; ) 是&lt;/p&gt;

&lt;p&gt;国内领先的纺织产业互联网践行者，我们为纺织 贸易 / 工业 企业提供软硬件结合的 SaaS 解决方案帮助传统企业对内提升企业运营效率对外依靠大小数据结合的方式链接产业上下游并提供 B2B 交易服务。&lt;/p&gt;

&lt;p&gt;目前产品功能覆盖了 交易、⽣产、质检、仓储、工业控制 ( 物联网 ) 等业务场景，终端覆盖了 TV、手机、PC、iPad、PDA 等设备，我们通过 SaaS 工具提升纺织企业交易/运营效率，同时通过实时数据监控、数据可视化、数据分析和数据追溯协助 企业做业务决策，用数据驱动业务增长。&lt;/p&gt;

&lt;p&gt;系统目前管理了⼏十亿的⾯料交易订单与几亿匹的布匹数据。UGG、Zara、海澜之家、七匹狼、Tommy、CK 等几十家知名服装厂商的面料供应商都在使用我们的产品。 &lt;/p&gt;
&lt;h2 id="融资情况 ？"&gt;融资情况？&lt;/h2&gt;
&lt;p&gt;我们已经获得一线的美元基金 贝塔斯曼亚洲投资基金（BAI）和 真格基金 的各数百万美元风险投资，其也是 UCloud、Keep、摩拜、哈罗单车、拉钩、寺库、网易云音乐等知名互联网公司的投资人&lt;/p&gt;

&lt;p&gt;相关媒体报道：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://36kr.com/p/5243898" rel="nofollow" target="_blank" title=""&gt;36 氪首发｜36 氪首发｜纺织业 SaaS「有数派」完成数百万美元 A 轮融资，由真格基金独家投资&lt;/a&gt; - &lt;code&gt;[36氪首发｜纺织业SaaS「有数派」完成数百万美元A轮融资，由真格基金独家投资](https://36kr.com/p/5243898)&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://36kr.com/p/5230465" rel="nofollow" target="_blank" title=""&gt;36 氪首发｜纺织业 SaaS「有数派」完成数百万美元 Pre-A 轮融资，BAI 独家投资&lt;/a&gt; - &lt;code&gt;[36氪首发｜纺织业SaaS「有数派」完成数百万美元Pre-A轮融资，BAI独家投资](https://36kr.com/p/5230465)&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.lieyunwang.com/archives/446073" rel="nofollow" target="_blank" title=""&gt;自主研发了技术架构 + 设计模式，有数派要帮助纺织企业更好地进行管理与运营&lt;/a&gt; - &lt;code&gt;[自主研发了技术架构+设计模式，有数派要帮助纺织企业更好地进行管理与运营](https://www.lieyunwang.com/archives/446073)&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://36kr.com/p/5148992" rel="nofollow" target="_blank" title=""&gt;当互联网嵌入传统纺织业，有数派想以 SaaS 工具切入 B2B 交易&lt;/a&gt; - &lt;code&gt;[当互联网嵌入传统纺织业，有数派想以SaaS工具切入B2B交易](https://36kr.com/p/5148992)&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="我们的工程师团队："&gt;我们的工程师团队：&lt;/h2&gt;
&lt;p&gt;目前我们的研发团队一共有 40 多位同事&lt;/p&gt;

&lt;p&gt;前端（React Native + React + iOS &amp;amp; Android）10 + 位&lt;/p&gt;

&lt;p&gt;后端（纯后端 Ruby）10 + 位&lt;/p&gt;

&lt;p&gt;产品 &amp;amp; 设计 若干&lt;/p&gt;

&lt;p&gt;我们来自：&lt;/p&gt;

&lt;p&gt;华兴资本、Tower、搜狐、阿里巴巴、华为、京东、美团、挖财、大搜车、多伦多大学、西北大学、湖南大学、电子科技大学 等一线互联网公司与高等学府。&lt;/p&gt;

&lt;p&gt;同时我们也赞助了去年上海的 RubyConf 活动&lt;/p&gt;
&lt;h2 id="我们的技术栈："&gt;我们的技术栈：&lt;/h2&gt;
&lt;p&gt;全套 GraphQL  + Ruby on rails + PG + React + React Native + MQTT（IoT） . &lt;/p&gt;

&lt;p&gt;我们可能是国内为数不多在后端架构上全套使用 GraphQL 技术的公司，目前用 GraphQL 支撑了 6 个客户端的业务覆盖了近 200 个 Model。&lt;/p&gt;

&lt;p&gt;团队撰写了国内第一本 GraphQL 中文书籍（即将出版） &amp;amp; GraphQL 布道者&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://www.huodongxing.com/event/7441170737900?from=groupmessage" rel="nofollow" target="_blank" title=""&gt;杭州第一届 GraphQLParty&lt;/a&gt; - &lt;code&gt;[杭州第一届 GraphQLParty](http://www.huodongxing.com/event/7441170737900?from=groupmessage)&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="我们在找什么样的人"&gt;我们在找什么样的人&lt;/h2&gt;&lt;h3 id="Ruby 工程师"&gt;Ruby 工程师&lt;/h3&gt;
&lt;p&gt;【基础要求】&lt;/p&gt;

&lt;p&gt;0、相信产业互联网的机会，并愿意投身传统行业改造浪潮的工程师&lt;/p&gt;

&lt;p&gt;1、3 年以上 Ruby on Rails 开发经验；&lt;/p&gt;

&lt;p&gt;2、具有扎实的语言基础，良好的面向对象编程思想；&lt;/p&gt;

&lt;p&gt;3、掌握常用的设计模式，了解移动互联网相关技术；&lt;/p&gt;

&lt;p&gt;4、熟悉 Linux 类环境，能熟练使用 Unix 类系统下的 ruby 编程；&lt;/p&gt;

&lt;p&gt;5、熟悉 MYSQL，PG 等至少一种关系型数据库；&lt;/p&gt;

&lt;p&gt;【加分项】&lt;/p&gt;

&lt;p&gt;1、有 Iot 工业产品或大规模数据应用开发经验者加分&lt;/p&gt;

&lt;p&gt;2、对前端技术有一定的应用者大大加分（React 方向）&lt;/p&gt;

&lt;p&gt;3、对 GraphQL 技术栈有一定的研究或者应用者大大加分&lt;/p&gt;

&lt;p&gt;【薪资 &amp;amp; HeadCount】&lt;/p&gt;

&lt;p&gt;薪资范围：15k - 30k&lt;/p&gt;

&lt;p&gt;本次招聘 2 位 后端工程师&lt;/p&gt;
&lt;h2 id="与我联系"&gt;与我联系&lt;/h2&gt;
&lt;p&gt;邮箱：1162040314 at qq.com（注明来源 ruby-china）
&lt;img src="https://l.ruby-china.com/photo/2019/c77ed3e9-30bd-4449-b539-71de05fb399e.jpg!large" title="" alt=""&gt;&lt;/p&gt;</description>
      <author>flydragon</author>
      <pubDate>Tue, 04 Feb 2020 10:16:36 +0800</pubDate>
      <link>https://ruby-china.org/topics/39480</link>
      <guid>https://ruby-china.org/topics/39480</guid>
    </item>
    <item>
      <title>[绍兴柯桥 / 杭州萧山] 有数派 诚聘 Ruby 后端、React、React Native 前端工程师 / 长期有效 ( 15K - 30K )</title>
      <description>&lt;h2 id="什么是有数派 ？"&gt;什么是有数派？&lt;/h2&gt;
&lt;p&gt;有数派  ( &lt;a href="https://youshupai.com" rel="nofollow" target="_blank"&gt;https://youshupai.com&lt;/a&gt; ) 是&lt;/p&gt;

&lt;p&gt;国内领先的纺织产业互联网践行者，我们为纺织 贸易 / 工业 企业提供软硬件结合的 SaaS 解决方案帮助传统企业对内提升企业运营效率对外依靠大小数据结合的方式链接产业上下游并提供 B2B 交易服务。&lt;/p&gt;

&lt;p&gt;目前产品功能覆盖了 交易、⽣产、质检、仓储、工业控制 ( 物联网 ) 等业务场景，终端覆盖了 TV、手机、PC、iPad、PDA 等设备，我们通过 SaaS 工具提升纺织企业交易/运营效率，同时通过实时数据监控、数据可视化、数据分析和数据追溯协助 企业做业务决策，用数据驱动业务增长。&lt;/p&gt;

&lt;p&gt;系统目前管理了⼏十亿的⾯料交易订单与几亿匹的布匹数据。UGG、Zara、海澜之家、七匹狼、Tommy、CK 等几十家知名服装厂商的面料供应商都在使用我们的产品。 &lt;/p&gt;
&lt;h2 id="融资情况 ？"&gt;融资情况？&lt;/h2&gt;
&lt;p&gt;我们已经获得一线的美元基金 贝塔斯曼亚洲投资基金（BAI）和 真格基金 的各数百万美元风险投资，其也是 UCloud、Keep、摩拜、哈罗单车、拉钩、寺库、网易云音乐等知名互联网公司的投资人&lt;/p&gt;

&lt;p&gt;相关媒体报道：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://36kr.com/p/5243898" rel="nofollow" target="_blank" title=""&gt;36 氪首发｜36 氪首发｜纺织业 SaaS「有数派」完成数百万美元 A 轮融资，由真格基金独家投资&lt;/a&gt; - &lt;code&gt;[36氪首发｜纺织业SaaS「有数派」完成数百万美元A轮融资，由真格基金独家投资](https://36kr.com/p/5243898)&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://36kr.com/p/5230465" rel="nofollow" target="_blank" title=""&gt;36 氪首发｜纺织业 SaaS「有数派」完成数百万美元 Pre-A 轮融资，BAI 独家投资&lt;/a&gt; - &lt;code&gt;[36氪首发｜纺织业SaaS「有数派」完成数百万美元Pre-A轮融资，BAI独家投资](https://36kr.com/p/5230465)&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.lieyunwang.com/archives/446073" rel="nofollow" target="_blank" title=""&gt;自主研发了技术架构 + 设计模式，有数派要帮助纺织企业更好地进行管理与运营&lt;/a&gt; - &lt;code&gt;[自主研发了技术架构+设计模式，有数派要帮助纺织企业更好地进行管理与运营](https://www.lieyunwang.com/archives/446073)&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://36kr.com/p/5148992" rel="nofollow" target="_blank" title=""&gt;当互联网嵌入传统纺织业，有数派想以 SaaS 工具切入 B2B 交易&lt;/a&gt; - &lt;code&gt;[当互联网嵌入传统纺织业，有数派想以SaaS工具切入B2B交易](https://36kr.com/p/5148992)&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="我们的工程师团队："&gt;我们的工程师团队：&lt;/h2&gt;
&lt;p&gt;目前我们的研发团队一共有 40 多位同事&lt;/p&gt;

&lt;p&gt;前端（React Native + React + iOS &amp;amp; Android）10 + 位&lt;/p&gt;

&lt;p&gt;后端（纯后端 Ruby）10 + 位&lt;/p&gt;

&lt;p&gt;产品 &amp;amp; 设计 若干&lt;/p&gt;

&lt;p&gt;我们来自：&lt;/p&gt;

&lt;p&gt;华兴资本、Tower、搜狐、阿里巴巴、华为、京东、美团、挖财、大搜车、多伦多大学、西北大学、湖南大学、电子科技大学 等一线互联网公司与高等学府。&lt;/p&gt;

&lt;p&gt;同时我们也赞助了今年上海的 RubyConf 活动&lt;/p&gt;
&lt;h2 id="我们的技术栈："&gt;我们的技术栈：&lt;/h2&gt;
&lt;p&gt;全套 GraphQL  + Ruby on rails + PG + React + React Native + MQTT（IoT） . &lt;/p&gt;

&lt;p&gt;我们可能是国内为数不多在后端架构上全套使用 GraphQL 技术的公司，目前用 GraphQL 支撑了 6 个客户端的业务覆盖了近 200 个 Model。&lt;/p&gt;

&lt;p&gt;团队撰写了国内第一本 GraphQL 中文书籍（即将出版） &amp;amp; GraphQL 布道者&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://www.huodongxing.com/event/7441170737900?from=groupmessage" rel="nofollow" target="_blank" title=""&gt;杭州第一届 GraphQLParty&lt;/a&gt; - &lt;code&gt;[杭州第一届 GraphQLParty](http://www.huodongxing.com/event/7441170737900?from=groupmessage)&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="我们在找什么样的人"&gt;我们在找什么样的人&lt;/h2&gt;&lt;h3 id="Ruby 工程师"&gt;Ruby 工程师&lt;/h3&gt;
&lt;p&gt;【基础要求】&lt;/p&gt;

&lt;p&gt;0、相信产业互联网的机会，并愿意投身传统行业改造浪潮的工程师&lt;/p&gt;

&lt;p&gt;1、1 年以上 Ruby on Rails 开发经验；&lt;/p&gt;

&lt;p&gt;2、具有扎实的语言基础，良好的面向对象编程思想；&lt;/p&gt;

&lt;p&gt;3、掌握常用的设计模式，了解移动互联网相关技术；&lt;/p&gt;

&lt;p&gt;4、熟悉 Linux 类环境，能熟练使用 Unix 类系统下的 ruby 编程；&lt;/p&gt;

&lt;p&gt;5、熟悉 MYSQL，PG 等至少一种关系型数据库；&lt;/p&gt;

&lt;p&gt;【加分项】&lt;/p&gt;

&lt;p&gt;1、有 Iot 工业产品或大规模数据应用开发经验者加分&lt;/p&gt;

&lt;p&gt;2、对前端技术有一定的应用者大大加分（React 方向）&lt;/p&gt;

&lt;p&gt;3、对 GraphQL 技术栈有一定的研究或者应用者大大加分&lt;/p&gt;

&lt;p&gt;【薪资 &amp;amp; HeadCount】&lt;/p&gt;

&lt;p&gt;薪资范围：15k - 30k&lt;/p&gt;

&lt;p&gt;本次招聘 5 位 后端工程师&lt;/p&gt;
&lt;h3 id="React 工程师"&gt;React 工程师&lt;/h3&gt;
&lt;p&gt;【基础要求】&lt;/p&gt;

&lt;p&gt;0、相信产业互联网的机会，并愿意投身传统行业改造浪潮的工程师&lt;/p&gt;

&lt;p&gt;1、3 年以上前端开发经验，精通各种 Web 前端的原理及技术；&lt;/p&gt;

&lt;p&gt;2、精通 React 全家桶，对 React, Redux 等源码及核心技术有一定的研究和自己的理解；&lt;/p&gt;

&lt;p&gt;3、对前端组件化和工程化有一定经验，熟悉 webpack，了解其原理并能进行一定的开发工作；&lt;/p&gt;

&lt;p&gt;4、熟悉函数式编程，熟悉 ES6 规范，掌握常用的 JS 设计模式，有良好的编码风格；&lt;/p&gt;

&lt;p&gt;5、对前端前沿技术保持热情的态度，例如 React Hooks, React Fiber，SSR 等； &lt;/p&gt;

&lt;p&gt;【加分项】&lt;/p&gt;

&lt;p&gt;1、有 Iot 工业产品或复杂企业后台应用开发经验者加分&lt;/p&gt;

&lt;p&gt;2、有小程序开发经验者加分&lt;/p&gt;

&lt;p&gt;3、对后端技术有实际项目开发经验者加分（Ruby 方向）&lt;/p&gt;

&lt;p&gt;4、对 GraphQL 技术栈有一定的研究或者应用者大大加分&lt;/p&gt;

&lt;p&gt;【薪资 &amp;amp; HeadCount】&lt;/p&gt;

&lt;p&gt;薪资范围：15k - 30k&lt;/p&gt;

&lt;p&gt;本次招聘 3 位 React 前端工程师&lt;/p&gt;
&lt;h3 id="React Native工程师"&gt;React Native 工程师&lt;/h3&gt;
&lt;p&gt;0、相信产业互联网的机会，并愿意投身传统行业改造浪潮的工程师&lt;/p&gt;

&lt;p&gt;1、3 年以上前端开发经验，1 年以上 React Native 开发经验，熟练掌握各种 Web 前端的原理及技术；&lt;/p&gt;

&lt;p&gt;2、熟悉 React 和 React Native 基本工作原理，有完整参与或主导过一个 React Ntive 实际项目开发经验；&lt;/p&gt;

&lt;p&gt;3、有一定 Android 或 iOS 原生研发能力；&lt;/p&gt;

&lt;p&gt;4、熟悉函数式编程，熟悉 ES6 规范，掌握常用的 JS 设计模式，有良好的编码风格；&lt;/p&gt;

&lt;p&gt;5、熟悉 React Native 性能优化&lt;/p&gt;

&lt;p&gt;【加分项】&lt;/p&gt;

&lt;p&gt;1、有 Iot 工业产品或复杂企业后台应用开发经验者加分&lt;/p&gt;

&lt;p&gt;2、有丰富的原生开发经验者加分（Android 或 iOS）&lt;/p&gt;

&lt;p&gt;3、对后端技术有实际项目开发经验者加分（Ruby 方向）&lt;/p&gt;

&lt;p&gt;4、对 GraphQL 技术栈有一定的研究或者应用者大大加分&lt;/p&gt;

&lt;p&gt;【薪资 &amp;amp; HeadCount】&lt;/p&gt;

&lt;p&gt;薪资范围：15k - 30k&lt;/p&gt;

&lt;p&gt;本次招聘 2 位 React Native 前端工程师&lt;/p&gt;
&lt;h2 id="与我联系"&gt;与我联系&lt;/h2&gt;
&lt;p&gt;邮箱：1162040314 at qq.com（注明来源 ruby-china）
&lt;img src="https://l.ruby-china.com/photo/2019/c77ed3e9-30bd-4449-b539-71de05fb399e.jpg!large" title="" alt=""&gt;&lt;/p&gt;</description>
      <author>flydragon</author>
      <pubDate>Thu, 17 Oct 2019 14:15:17 +0800</pubDate>
      <link>https://ruby-china.org/topics/39164</link>
      <guid>https://ruby-china.org/topics/39164</guid>
    </item>
    <item>
      <title>乐观锁这次应该说清楚了吧</title>
      <description>&lt;h3 id="概要"&gt;概要&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;希望从实例到源代码，逐步解析乐观锁的工作流程，希望对你有所帮助。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="实例"&gt;实例&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# 添加lock_version列&lt;/span&gt;
&lt;span class="no"&gt;Store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;attribute_names&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; ["id", "name", "number", "lock_version", "created_at", "updated_at"]&lt;/span&gt;

&lt;span class="n"&gt;s1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;
&lt;span class="n"&gt;s2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;

&lt;span class="n"&gt;s1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;number&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt; &lt;span class="c1"&gt;# 正常&lt;/span&gt;

&lt;span class="n"&gt;s2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;number&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="n"&gt;s2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt; &lt;span class="c1"&gt;# 异常&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- sql日志&lt;/span&gt;
&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="nv"&gt;`stores`&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="nv"&gt;`number`&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;`updated_at`&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'2019-05-11 01:15:19'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;`lock_version`&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="nv"&gt;`stores`&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;`id`&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="nv"&gt;`stores`&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;`lock_version`&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="实例分析"&gt;实例分析&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;递增 lock_version 追加到更新字段后面 (&lt;code&gt;lock_version = 1&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;当前 lock_version 合并到更新条件后面 (&lt;code&gt;lock_version = 0&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;执行更新 sql，返回更新行数，理论上如果没有并发的话，受影响行数一定为 1。

&lt;ul&gt;
&lt;li&gt;更新行数为 1，说明当前版本号最新，期间无并发操作。&lt;/li&gt;
&lt;li&gt;更新行数不为 1，说明当前版本号失效，有并发操作，抛出异常&lt;code&gt;ActiveRecord::StaleObjectError&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="源代码分析"&gt;源代码分析&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;代码位置&lt;code&gt;ActiveRecord::Locking::Optimistic&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_update_row&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attribute_names&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;attempted_action&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"update"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;locking_enabled?&lt;/span&gt;

  &lt;span class="k"&gt;begin&lt;/span&gt;
    &lt;span class="c1"&gt;# 获取乐观锁版本控制列，默认为lock_version&lt;/span&gt;
    &lt;span class="n"&gt;locking_column&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;locking_column&lt;/span&gt;
    &lt;span class="n"&gt;previous_lock_value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;read_attribute_before_type_cast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;locking_column&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# lock_version追加到更新字段中&lt;/span&gt;
    &lt;span class="n"&gt;attribute_names&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;locking_column&lt;/span&gt;

    &lt;span class="c1"&gt;# lock_version + 1&lt;/span&gt;
    &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;locking_column&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

    &lt;span class="c1"&gt;# 执行更新操作，返回受影响行数&lt;/span&gt;
    &lt;span class="c1"&gt;# 更新字段：attribute_names + lock_version&lt;/span&gt;
    &lt;span class="c1"&gt;# 查询条件：primary_key + lock_version&lt;/span&gt;
    &lt;span class="n"&gt;affected_rows&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_update_record&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="n"&gt;attributes_with_values&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attribute_names&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="c1"&gt;# 更新字段&lt;/span&gt;
      &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;primary_key&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;id_in_database&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# 主键查询条件&lt;/span&gt;
      &lt;span class="n"&gt;locking_column&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;previous_lock_value&lt;/span&gt; &lt;span class="c1"&gt;# 版本号查询条件&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# 受影响行数不为1，则说明有并发，抛出异常&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;affected_rows&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
      &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;StaleObjectError&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;attempted_action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="n"&gt;affected_rows&lt;/span&gt;

  &lt;span class="c1"&gt;# If something went wrong, revert the locking_column value.&lt;/span&gt;
  &lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="no"&gt;Exception&lt;/span&gt;
    &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;locking_column&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;previous_lock_value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_i&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="总结"&gt;总结&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;更新时检查当前读取记录 lock_version 是否为最新，来判断是否有并发的存在。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;乐观锁通过版本号来检测并发&lt;/li&gt;
&lt;li&gt;检测的条件是，在当前记录版本号下执行更新受影响的行数是否为 1&lt;/li&gt;
&lt;li&gt;出现并发抛出异常&lt;code&gt;ActiveRecord::StaleObjectError&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;并发处理，需要手动处理（捕获异常-》并发处理）&lt;/li&gt;
&lt;li&gt;处理方法包括重试，具体可参考&lt;a href="https://ruby-china.org/topics/28963" title=""&gt;Rails 中乐观锁与悲观锁的使用&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;</description>
      <author>flydragon</author>
      <pubDate>Sat, 11 May 2019 09:46:51 +0800</pubDate>
      <link>https://ruby-china.org/topics/38507</link>
      <guid>https://ruby-china.org/topics/38507</guid>
    </item>
    <item>
      <title>集合缓存优化实践</title>
      <description>&lt;h2 id="场景"&gt;场景&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;对获取列表的 api 接口进行集合缓存，假设获取前 10 条文章列表。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="优化前"&gt;优化前&lt;/h2&gt;&lt;h3 id="关键代码"&gt;关键代码&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# model&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Article&lt;/span&gt;
  &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;Mongoid&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Document&lt;/span&gt;
  &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;Mongoid&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Timestamps&lt;/span&gt;

  &lt;span class="n"&gt;field&lt;/span&gt; &lt;span class="ss"&gt;:title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;type: &lt;/span&gt;&lt;span class="no"&gt;String&lt;/span&gt;
  &lt;span class="n"&gt;field&lt;/span&gt; &lt;span class="ss"&gt;:content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;type: &lt;/span&gt;&lt;span class="no"&gt;String&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# controller&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ArticlesController&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Api&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;BaseController&lt;/span&gt;
   &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;index&lt;/span&gt;
      &lt;span class="vi"&gt;@articles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Article&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;order_by&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;id: :asc&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# view&lt;/span&gt;
&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cache!&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="vi"&gt;@articles&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;articles&lt;/span&gt; &lt;span class="vi"&gt;@articles&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="调起api的数据库log"&gt;调起 api 的数据库 log&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# 第一次调用api&lt;/span&gt;
&lt;span class="no"&gt;MONGODB&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;localhost&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;27017&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;_development&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="no"&gt;STARTED&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"find"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;"articles"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"filter"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="s2"&gt;"limit"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"sort"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
&lt;span class="c1"&gt;# 第二次调用api&lt;/span&gt;
&lt;span class="no"&gt;MONGODB&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;localhost&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;27017&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;_development&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="no"&gt;STARTED&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"find"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;"articles"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"filter"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="s2"&gt;"limit"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"sort"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="优化后"&gt;优化后&lt;/h2&gt;&lt;h3 id="关键代码"&gt;关键代码&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# 处理类数据的缓存键（新增）&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;ClassDataCacheKeyAble&lt;/span&gt;
  &lt;span class="kp"&gt;extend&lt;/span&gt; &lt;span class="no"&gt;ActiveSupport&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Concern&lt;/span&gt;

  &lt;span class="n"&gt;included&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;after_create&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;refresh_class_cache_version&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="n"&gt;after_update&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;refresh_class_cache_version&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="n"&gt;after_destroy&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;refresh_class_cache_version&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;class_methods&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;cache_key_with_version&lt;/span&gt;
      &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;cache_key&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;-&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;cache_version&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;cache_version&lt;/span&gt;
      &lt;span class="no"&gt;Redis&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Counter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"class_cache_version:&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;cache_key&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;value&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;refresh_class_cache_version&lt;/span&gt;
      &lt;span class="no"&gt;Redis&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Counter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"class_cache_version:&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;cache_key&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;increment&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;cache_key&lt;/span&gt;
      &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tableize&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# model调整&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Article&lt;/span&gt;
  &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;Mongoid&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Document&lt;/span&gt;
  &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;Mongoid&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Timestamps&lt;/span&gt;
  &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;ClassDataCacheKeyAble&lt;/span&gt; &lt;span class="c1"&gt;# 引入模块&lt;/span&gt;

  &lt;span class="n"&gt;field&lt;/span&gt; &lt;span class="ss"&gt;:title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;type: &lt;/span&gt;&lt;span class="no"&gt;String&lt;/span&gt;
  &lt;span class="n"&gt;field&lt;/span&gt; &lt;span class="ss"&gt;:content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;type: &lt;/span&gt;&lt;span class="no"&gt;String&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# view调整&lt;/span&gt;
&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cache!&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;Article&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;articles&lt;/span&gt; &lt;span class="vi"&gt;@articles&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="调起api的数据库log"&gt;调起 api 的数据库 log&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# 第一次调用api&lt;/span&gt;
&lt;span class="no"&gt;MONGODB&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;localhost&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;27017&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;_development&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="no"&gt;STARTED&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"find"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;"articles"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"filter"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="s2"&gt;"limit"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"sort"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
&lt;span class="c1"&gt;# 第二次调用api，没有查询数据库&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;相对优化前，减少了一次数据的列表查询，但多了一次获取全局更新键的 redis 查询，总体下来性能还是很好的，本地简单测试了一下近两倍左右，随着数据库数量的增加，优化空间会更大。  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;适用场景：模型总体数据变化不大，例子仅说明问题使用。  &lt;/p&gt;

&lt;p&gt;大家有没什么更好的方案，欢迎留言指正。&lt;/p&gt;</description>
      <author>flydragon</author>
      <pubDate>Sun, 27 Jan 2019 20:23:24 +0800</pubDate>
      <link>https://ruby-china.org/topics/38056</link>
      <guid>https://ruby-china.org/topics/38056</guid>
    </item>
    <item>
      <title>[北京] 网利宝招聘 Rails 程序员 2 名</title>
      <description>&lt;h2 id="公司相关"&gt;公司相关&lt;/h2&gt;&lt;h3 id="简介"&gt;简介&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;由于介绍太过冗余，所以就提供相关链接&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;网利宝隶属于网利金融，2014 年 9 月正式上线，是一家网贷信息中介平台。&lt;/p&gt;
&lt;h3 id="相关链接"&gt;相关链接&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.wanglibao.com/" rel="nofollow" target="_blank" title=""&gt;公司官网&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.lagou.com/gongsi/14819.html" rel="nofollow" target="_blank" title=""&gt;拉钩公司主页&lt;/a&gt;，&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="坐标"&gt;坐标&lt;/h3&gt;
&lt;p&gt;北京市朝阳区三元桥海南航空大厦 A 座&lt;/p&gt;
&lt;h3 id="简历投递邮箱"&gt;简历投递邮箱&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;欢迎骚扰^^&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;congfengzhi@wanglibank.com&lt;/p&gt;
&lt;h2 id="薪资待遇"&gt;薪资待遇&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;目前能确定的&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;月薪 10k~25k（能力而定）&lt;/li&gt;
&lt;li&gt;双休&lt;/li&gt;
&lt;li&gt;五险一金&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="主要职责"&gt;主要职责&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;负责公司新项目的开发，目前主要做小程序后端。现有小程序【财商王者】&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;模型设计&lt;/li&gt;
&lt;li&gt;后台管理系统的开发&lt;/li&gt;
&lt;li&gt;api 接口开发&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="职位要求"&gt;职位要求&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;学历不限，主要看能力&lt;/li&gt;
&lt;li&gt;良好的沟通能力和学习能力（特别注重）&lt;/li&gt;
&lt;li&gt;一年以上 ruby on rails 开发经验&lt;/li&gt;
&lt;li&gt;熟悉 ruby 元编程，有良好的代码风格（参考 ruby-style-guide）&lt;/li&gt;
&lt;li&gt;熟悉 mongodb redis 数据库&lt;/li&gt;
&lt;li&gt;了解 HTML、CSS、JavaScript&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="附加说明"&gt;附加说明&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;本着坦诚的态度，大家有其他疑问可以评论区提问，我会依次回复&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;愿意培养新人吗？&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;愿意，但是也希望你有很强的求知欲和良好的态度&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;你们公司会加班吗？&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;有时候会的，项目急得话会加班，但不频繁。&lt;br&gt;
我经历了最长的一次加班是 5 天，每天加到 10 点，但是这种经历在一年中发生过 3 次&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ol&gt;</description>
      <author>flydragon</author>
      <pubDate>Thu, 06 Dec 2018 12:01:46 +0800</pubDate>
      <link>https://ruby-china.org/topics/37865</link>
      <guid>https://ruby-china.org/topics/37865</guid>
    </item>
    <item>
      <title>autoload 用法小结</title>
      <description>&lt;h2 id="摘要"&gt;摘要&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;分别梳理三种不同的用法&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;内核 (&lt;code&gt;Kernel.autoload&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;模块 (&lt;code&gt;Module.autoload&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Rails 扩展 (&lt;code&gt;ActiveSupport::Autoload&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h2 id="内核方法(Kernel.autoload)"&gt;内核方法 (&lt;code&gt;Kernel.autoload&lt;/code&gt;)&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Registers filename to be loaded (using Kernel::require) the first time that module (which may be a String or a symbol) is accessed&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;当常量首次访问时，进行&lt;code&gt;require&lt;/code&gt;加载，节约内存。&lt;/li&gt;
&lt;li&gt;相当于&lt;code&gt;require&lt;/code&gt;的智能模式&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3 id="实例代码"&gt;实例代码&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# /home/deploy/a.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;A&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hi&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;'hi i am module A'&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="nb"&gt;puts&lt;/span&gt;  &lt;span class="s1"&gt;'file a.rb has load'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="autoload模式"&gt;autoload 模式&lt;/h4&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# irb&lt;/span&gt;
&lt;span class="nb"&gt;autoload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'/home/deploy/demo.rb'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="no"&gt;A&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hi&lt;/span&gt; 
&lt;span class="c1"&gt;# =&amp;gt; file a.rb has load&lt;/span&gt;
&lt;span class="c1"&gt;# hi i am module A&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="require模式"&gt;require 模式&lt;/h4&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# irb&lt;/span&gt;

&lt;span class="c1"&gt;# 执行后，文件立即被加载&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'/home/deploy/demo/a.rb'&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; file a.rb has load&lt;/span&gt;

&lt;span class="no"&gt;A&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hi&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; hi i am module A&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="模块方法(Module.autoload)"&gt;模块方法 (&lt;code&gt;Module.autoload&lt;/code&gt;)&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Registers filename to be loaded (using Kernel::require) the first time that module (which may be a String or a symbol) is accessed in the namespace of mod.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;当常量在指定命名空间内访问时，进行文件加载&lt;/li&gt;
&lt;li&gt;相当于受保护的&lt;code&gt;require&lt;/code&gt;的智能模式&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3 id="实例代码"&gt;实例代码&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# /home/deploy/a.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;A&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hi&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;'hi i am module A'&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;B&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hi&lt;/span&gt;
      &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;'hi i am module B'&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;'file a has load'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="运行"&gt;运行&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;当访问&lt;code&gt;A:B&lt;/code&gt;时加载文件&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# irb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;A&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="no"&gt;A&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;autoload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'/home/deploy/a.rb'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="no"&gt;A&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;B&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hi&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; file a has load&lt;/span&gt;
&lt;span class="c1"&gt;# hi i am module B&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="Rails 扩展(ActiveSupport::Autoload)"&gt;Rails 扩展 (&lt;code&gt;ActiveSupport::Autoload&lt;/code&gt;)&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;内核&lt;code&gt;autoload&lt;/code&gt;方法的扩展，在约定的路径 (&lt;code&gt;ActiveSupport::Inflector.underscore&lt;/code&gt;) 中加载文件&lt;/li&gt;
&lt;li&gt;省去了写具体路径麻烦&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rails/rails/blob/0488d0021190970c894b30bd2b4b05fbeaa75f83/activesupport/lib/active_support/dependencies/autoload.rb#L35" rel="nofollow" target="_blank" title=""&gt;详细实现可以查看源码&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="代码目录"&gt;代码目录&lt;/h3&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;lib/
  sso.rb
  sso
    a.rb
    b.rb
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="实例代码"&gt;实例代码&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# lib/sso.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Sso&lt;/span&gt;
  &lt;span class="kp"&gt;extend&lt;/span&gt; &lt;span class="no"&gt;ActiveSupport&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Autoload&lt;/span&gt;

  &lt;span class="nb"&gt;autoload&lt;/span&gt; &lt;span class="ss"&gt;:A&lt;/span&gt;
  &lt;span class="nb"&gt;autoload&lt;/span&gt; &lt;span class="ss"&gt;:B&lt;/span&gt;
  &lt;span class="nb"&gt;autoload&lt;/span&gt; &lt;span class="ss"&gt;:C&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# lib/sso/a.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Sso&lt;/span&gt;
  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;A&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hi&lt;/span&gt;
      &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;'hi i am module A'&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;'file a has load'&lt;/span&gt;

&lt;span class="c1"&gt;# lib/sso/a.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Sso&lt;/span&gt;
  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;B&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hi&lt;/span&gt;
      &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;'hi i am module B'&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;'file b has load'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="运行"&gt;运行&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# rails c&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'sso'&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;

&lt;span class="c1"&gt;# 加载sso/a文件&lt;/span&gt;
&lt;span class="no"&gt;Sso&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;A&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hi&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt;&lt;/span&gt;
          &lt;span class="c1"&gt;# file a has load&lt;/span&gt;
          &lt;span class="c1"&gt;# hi i am module A&lt;/span&gt;

&lt;span class="c1"&gt;# 加载sso/b文件&lt;/span&gt;
&lt;span class="no"&gt;Sso&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;B&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hi&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt;&lt;/span&gt;
          &lt;span class="c1"&gt;# file b has load&lt;/span&gt;
          &lt;span class="c1"&gt;# hi i am module B&lt;/span&gt;

&lt;span class="c1"&gt;# 加载sso/c文件&lt;/span&gt;
&lt;span class="no"&gt;Sso&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;C&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hi&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; LoadError: cannot load such file -- sso/c         &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;</description>
      <author>flydragon</author>
      <pubDate>Tue, 04 Sep 2018 19:20:51 +0800</pubDate>
      <link>https://ruby-china.org/topics/37437</link>
      <guid>https://ruby-china.org/topics/37437</guid>
    </item>
    <item>
      <title>aws s3 客户端主秘钥解密很慢的问题？</title>
      <description>&lt;h2 id="前置说明"&gt;前置说明&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;使用亚马逊的 s3 储存敏感数据，使用了客户端主秘钥（非对称加密）的方式处理文件加密。&lt;/li&gt;
&lt;li&gt;rsa 秘钥长度为 1024&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="主代码"&gt;主代码&lt;/h2&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;rsa&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'./private_key.pem'&lt;/span&gt;
&lt;span class="n"&gt;region&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'ap-southeast-1'&lt;/span&gt;
&lt;span class="n"&gt;bucket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'target-bucket'&lt;/span&gt;
&lt;span class="n"&gt;key&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'remote.target.tar.gz'&lt;/span&gt;

&lt;span class="n"&gt;s3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Aws&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;S3&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Encryption&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;encryption_key: &lt;/span&gt;&lt;span class="no"&gt;OpenSSL&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;PKey&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;RSA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rsa&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="ss"&gt;region: &lt;/span&gt;&lt;span class="n"&gt;region&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_object&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;response_target: &lt;/span&gt;&lt;span class="s1"&gt;'./local_target.tar.gz'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;bucket: &lt;/span&gt;&lt;span class="n"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;key: &lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="问题"&gt;问题&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;解密一个 20m 的文件时，时间超过 4 小时，请问各位大神有没有遇到同样的问题？求建议&lt;/strong&gt;&lt;/p&gt;</description>
      <author>flydragon</author>
      <pubDate>Thu, 22 Mar 2018 12:34:59 +0800</pubDate>
      <link>https://ruby-china.org/topics/35286</link>
      <guid>https://ruby-china.org/topics/35286</guid>
    </item>
  </channel>
</rss>
