欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

分析Cache 在 Ruby China 里面的應用情況

 更新時間:2014年06月27日 09:57:27   投稿:hebedich  
之前文章介紹《web 應用中常用的各種 cache詳解》,今天來分享一下在 Ruby China 里面,我們是如何做 Cache 的。

首先給大家看一下 NewRelic 的報表

最近 24h 的平均響應時間

流量高的那些頁面 (Action)

訪問量搞的幾個 Action 的情況:

TopicsController#show

UsersController#show (比較慘,主要是 GitHub API 請求拖慢)

PS: 在發(fā)布這篇文章之前我有稍加修改了一下,GitHub 請求放到后臺隊列處理,新的結果是這樣:

TopicsController#index

HomeController#index

從上面的報表來看,目前 Ruby China 后端的請求,排除用戶主頁之外,響應時間都在 100ms 以內(nèi),甚至更低。

我們是如何做到的?

Markdown 緩存
Fragment Cache
數(shù)據(jù)緩存
ETag
靜態(tài)資源緩存 (JS,CSS,圖片)
Markdown 緩存

在內(nèi)容修改的時候就算好 Markdown 的結果,存到數(shù)據(jù)庫,避免瀏覽的時候反復計算。

此外這個東西也特意不放到 Cache,而是放到數(shù)據(jù)庫里面:

為了持久化,避免 Memcached 停掉的時候,大量丟失;
避免過多占用緩存內(nèi)存;

class Topic
 field :body # 存放原始內(nèi)容,用于修改
 field :body_html # 存放計算好的結果,用于顯示

 before_save :markdown_body
 def markdown_body
  self.body_html = MarkdownTopicConverter.format(self.body) if self.body_changed?
 end
end
Fragment Cache

這個是 Ruby China 里面用得最多的緩存方案,也是速度提升的原因所在。

app/views/topics/_topic.html.erb

<% cache([topic, suggest]) do %>
<div class="topic topic_line topic_<%= topic.id %>">
  <%= link_to(topic.replies_count,"#{topic_path(topic)}#reply#{topic.replies_count}",
     :class => "count state_false") %>
 ... 省略內(nèi)容部分

</div>
<% end %>

用 topic 的 cache_key 作為緩存 cache views/topics/{編號}-#{更新時間}/{suggest 參數(shù)}/{文件內(nèi)容 MD5} -> views/topics/19105-20140508153844/false/bc178d556ecaee49971b0e80b3566f12
某些涉及到根據(jù)用戶帳號,有不同狀態(tài)顯示的地方,直接把完整 HTML 準備好,通過 JS 控制狀態(tài),比如目前的“喜歡“功能。

<script type="text/javascript">
 var readed_topic_ids = <%= current_user.filter_readed_topics(@topics) %>;
 for (var i = 0; i < readed_topic_ids.length; i++) {
  topic_id = readed_topic_ids[i];
  $(".topic_"+ topic_id + " .right_info .count").addClass("state_true");
 }
</script>

再比如

app/views/topics/_reply.html.erb

 <% cache([reply,"raw:#{@show_raw}"]) do %>
<div class="reply">
 <div class="pull-left face"><%= user_avatar_tag(reply.user, :normal) %></div>
 <div class="infos">
  <div class="info">
   <span class="name">
    <%= user_name_tag(reply.user) %>
   </span>
   <span class="opts">
    <%= likeable_tag(reply, :cache => true) %>
    <%= link_to("", edit_topic_reply_path(@topic,reply), :class => "edit icon small_edit", 'data-uid' => reply.user_id, :title => "修改回帖")%>
    <%= link_to("", "#", 'data-floor' => floor, 'data-login' => reply.user_login,
      :title => t("topics.reply_this_floor"), :class => "icon small_reply" )
    %>
   </span>
  </div>
  <div class="body">
   <%= sanitize_reply reply.body_html %>
  </div>
 </div>
</div>
<% end %>

同樣也是通過 reply 的 cache_key 來緩存 views/replies/202695-20140508081517/raw:false/d91dddbcb269f3e0172bf5d0d27e9088

同時這里還有復雜的用戶權限控制,用 JS 實現(xiàn);

<script type="text/javascript">
 $(document).ready(function(){
  <% if admin? %>
   $("#replies .reply a.edit").css('display','inline-block');
  <% elsif current_user %>
   $("#replies .reply a.edit[data-uid='<%= current_user.id %>']").css('display','inline-block');
  <% end %>
  <% if current_user && !@user_liked_reply_ids.blank? %>
   Topics.checkRepliesLikeStatus([<%= @user_liked_reply_ids.join(",") %>]);
  <% end %>
 })
</script>

數(shù)據(jù)緩存

其實 Ruby China 的大多數(shù) Model 查詢都沒有上 Cache 的,因為據(jù)實際狀況來看, MongoDB 的查詢響應時間都是很快的,大部分場景都是在 5ms 以內(nèi),甚至更低。

我們會做一些比價負責的數(shù)據(jù)查詢緩存,比如:GitHub Repos 獲取

def github_repos(user_id)
 cache_key = "user:#{user_id}:github_repos"
 items = Rails.cache.read(cache_key)
 if items.blank?
  items = real_fetch_from_github()
  Rails.cache.write(cache_key, items, expires_in: 15.days)
 end
 return items
end
ETag

ETag 是在 HTTP Request, Response 可以帶上的一個參數(shù),用于檢測內(nèi)容是否有更新過,以減少網(wǎng)絡開銷。

過程大概是這樣

Rails 的 fresh_when 方法可以幫助將你的查詢內(nèi)容生成 ETag 信息

def show
 @topic = Topic.find(params[:id])

 fresh_when(etag: [@topic])
end

靜態(tài)資源緩存

請不要小看這個東西,后端寫得再快,也有可能被這些拖慢(瀏覽器上面的表現(xiàn))!

1、合理利用 Rails Assets Pipeline,一定要開啟!

# config/environments/production.rb
config.assets.digest = true

2、在 Nginx 里面將 CSS, JS, Image 的緩存有效期設成 max;

location ~ (/assets|/favicon.ico|/*.txt) {
 access_log    off;
 expires      max;
 gzip_static on;
}

3、盡可能的減少一個頁面 JS, CSS, Image 的數(shù)量,簡單的方法是合并它們,減少 HTTP 請求開銷;

<head>
 ... 
 只有兩個
 <link  rel="stylesheet" />
 <script src="http://ruby-china-files.b0.upaiyun.com/assets/app-24d4280cc6fda926e73419c126c71206.js"></script>
 ...
</head>

一些 Tips

看統(tǒng)計日志,優(yōu)先處理流量高的頁面;
updated_at 是一個非常有利于幫助你清理緩存的東西,善用它!修改數(shù)據(jù)的時候別忽略它!
多關注你的 Rails Log 里面的查詢時間,100ms 一下的頁面響應時間是一個比較好的狀態(tài),超過 200ms 用戶就會感覺到遲鈍了。

相關文章

  • Ruby中proc和lambda的兩個區(qū)別

    Ruby中proc和lambda的兩個區(qū)別

    這篇文章主要介紹了Ruby中proc和lambda的兩個區(qū)別,本文講解了在proc和lambda中,return關鍵字有不同含義、檢查參數(shù)的方式不同兩個重要區(qū)別,需要的朋友可以參考下
    2015-05-05
  • Ruby對比Python的優(yōu)勢和劣勢

    Ruby對比Python的優(yōu)勢和劣勢

    這篇文章主要介紹了Ruby對比Python的優(yōu)勢和劣勢,本文分別介紹了Ruby 比 Python 的優(yōu)勢和劣勢,幫助你選擇哪種語言來學習,需要的朋友可以參考下
    2015-05-05
  • Ruby中使用多線程隊列(Queue)實現(xiàn)下載博客文章保存到本地文件

    Ruby中使用多線程隊列(Queue)實現(xiàn)下載博客文章保存到本地文件

    這篇文章主要介紹了Ruby中使用多線程隊列(Queue)實現(xiàn)下載博客文章保存到本地文件,本文給出了實現(xiàn)代碼、并對代碼的核心部分做了講解,同時給出了運行效果圖,需要的朋友可以參考下
    2015-01-01
  • 淺析Ruby中的正則表達式的使用

    淺析Ruby中的正則表達式的使用

    這篇文章主要介紹了淺析Ruby中的正則表達式的使用,作者根據(jù)Ruby對正則表達式的支持提出了其中一些需要注意的地方,需要的朋友可以參考下
    2015-08-08
  • ruby實現(xiàn)網(wǎng)頁圖片抓取

    ruby實現(xiàn)網(wǎng)頁圖片抓取

    本文給大家分享的是個人使用ruby編寫的抓取網(wǎng)頁圖片的代碼,十分的簡單實用,有需要的小伙伴可以參考下。
    2015-06-06
  • ruby 存取器 概念

    ruby 存取器 概念

    ruby 存取器 概念...
    2007-11-11
  • 解析proxy代理模式在Ruby設計模式開發(fā)中的運用

    解析proxy代理模式在Ruby設計模式開發(fā)中的運用

    這篇文章主要介紹了proxy代理模式在Ruby設計模式開發(fā)中的運用,通過代理模式以客戶透明的形式可以動態(tài)地為目標對象加以行為控制,需要的朋友可以參考下
    2016-04-04
  • ruby 去掉文件里重復的行

    ruby 去掉文件里重復的行

    以前合并后臺字典時,有重復的都是用vbs去,最近又看了一天的ruby,想起來寫一下,沒想到代碼如此精簡
    2009-04-04
  • ruby聲明式語法的實現(xiàn)例子

    ruby聲明式語法的實現(xiàn)例子

    這篇文章主要介紹了ruby聲明式語法的實現(xiàn)例子,聲明式編程是一種編程范型,與命令式編程相對立,需要的朋友可以參考下
    2014-11-11
  • Ruby中Hash哈希結構的基本操作方法小結

    Ruby中Hash哈希結構的基本操作方法小結

    Hash是一種鍵值對應的數(shù)據(jù)結構,Ruby中直接帶有Hash類來對其提供支持,這里我們整理了Ruby中Hash哈希結構的基本操作方法小結,首先來回顧一下Hash的基本知識:
    2016-06-06

最新評論