1. 程式人生 > >3秒鐘完成50萬條併發日誌 檔案寫入

3秒鐘完成50萬條併發日誌 檔案寫入

前言

目前本人從事 JAVA開發 

之前講過《你的日誌元件記錄夠清晰嘛?--自己開發日誌元件 Logger》 日誌檔案,當你是羨慕java下面的log4j,列印日誌夠清晰,可以很清晰定位列印日誌所在檔案,行號等;

於是嘗試了重寫了日誌元件來模擬清晰列印;

序言

最近和群裡大佬們研究遊戲伺服器架構的時候,討論像魔獸,完美國際等遊戲世界場景無縫地圖實現方案;討論兩週後開始動手BB自己的伺服器架構已經執行緒模型規劃;

以上是最新伺服器架構圖;具體現在不BB,也不介紹具體關係,今天的重點是日誌

然後出現一個問題,就是當伺服器承載3000左右,log4j在高併發下 導致我的所有執行緒BLOCK了;咳咳;

也算是遇到了;當時想的是log4j比較是比較老的版本,很多東西肯定不是很適用了,想著換log4j2,再次進行測試,當伺服器承載到5000的時候依然所有執行緒BLOCK;

當時在網上尋求各種解決辦法依然未能解決我的執行緒BLOCK,於是我只能再一次走上重複造輪子的道路;

想起了以前的寫的日誌元件,翻頁成java版本;

PS:本人有一個習慣,就是類似架構或者程式碼,習慣用java和C#各寫一遍;

重點是程式碼,

 C#.net重構

 

本次工作重點是對之前版本進行迭代和重構;

重點優化是程式碼的結構,讓程式碼更清晰;思路更清晰;

重要的是加入磁碟io的雙緩衝區來解決寫入速度,提高io效率;

本次重點加入可讀取配置檔案模組

  1 using System;
  2 using System.Collections.Generic;
  3 using System.IO;
4 using System.Linq; 5 using System.Text; 6 using System.Threading.Tasks; 7 8 /** 9 * 10 * @author 失足程式設計師 11 * @Blog http://www.cnblogs.com/ty408/ 12 * @mail [email protected] 13 * @phone 13882122019 14 * 15 */ 16 namespace Net.Sz.Framework.Szlog 17 { 18 19 /// <summary>
20 /// 初始化輔助函式 21 /// 22 /// <para>預設是不列印棧楨的,因為比較耗時:如果需要請設定 LOGSTACKTRACE = true 或者 ↓↓↓</para> 23 /// <para>AppSettings 設定 log_print_stackrace 日誌是否輸出呼叫棧楨 true or false</para> 24 /// <para>AppSettings 設定 log_print_console 日誌是否輸出到控制檯 true or false</para> 25 /// <para>AppSettings 設定 log_print_level 日誌的等級,忽律大小寫 DEBUG INFO WARN ERROR</para> 26 /// <para>AppSettings 設定 log_print_path 日誌的檔名帶目錄,log/sz.log</para> 27 /// <para>AppSettings 設定 log_print_file 日誌是否輸出到檔案 true or false</para> 28 /// <para>AppSettings 設定 log_print_file_buffer 日誌雙緩衝輸出到檔案 true or false</para> 29 /// </summary> 30 public class CommUtil 31 { 32 /// <summary> 33 /// 日誌路徑儲存 34 /// </summary> 35 internal static string LOGPATH = "log/sz.log"; 36 37 /// <summary> 38 /// 日誌等級 39 /// <para>預設 LogLevel.DEBUG 列印</para> 40 /// </summary> 41 public static LogLevel LOG_PRINT_LEVEL = LogLevel.DEBUG; 42 43 /// <summary> 44 /// 是否顯示控制檯訊息 45 /// <para>預設 true 列印</para> 46 /// </summary> 47 public static bool LOG_PRINT_CONSOLE = true; 48 49 /// <summary> 50 /// 是否輸出檔案訊息 51 /// <para>預設 true 列印</para> 52 /// </summary> 53 public static bool LOG_PRINT_FILE = true; 54 /// <summary> 55 /// 輸出日誌到檔案的時候使用buff雙緩衝減少磁碟IO,可能導致日誌列印不及時 56 /// <para>雙緩衝對輸出到控制檯不受印象</para> 57 /// <para>預設 true</para> 58 /// </summary> 59 public static bool LOG_PRINT_FILE_BUFFER = true; 60 61 /// <summary> 62 /// 是否列印棧楨 63 /// <para>預設 false 不列印</para> 64 /// </summary> 65 public static bool LOG_PRINT_STACKTRACE = false; 66 67 68 /// <summary> 69 /// 設定日誌輸出目錄 70 /// </summary> 71 /// <param name="path"></param> 72 static public void SetLogRootPath(string logPath) 73 { 74 ResetLogDirectory(logPath); 75 LOGPATH = logPath; 76 } 77 78 /// <summary> 79 /// 構建輸出目錄 80 /// </summary> 81 /// <param name="logPath"></param> 82 static public void ResetLogDirectory(string logPath) 83 { 84 string bpath = System.IO.Path.GetDirectoryName(logPath); 85 if (!Directory.Exists(bpath)) { Directory.CreateDirectory(bpath); } 86 } 87 88 89 /// <summary> 90 /// 友好方法,不對外,初始化 91 /// </summary> 92 internal static void InitConfig() 93 { 94 if (System.Configuration.ConfigurationManager.AppSettings.AllKeys.Contains("log_print_path")) 95 { 96 string log_print_path = System.Configuration.ConfigurationManager.AppSettings["log_print_path"].ToString(); 97 SetLogRootPath(log_print_path); 98 } 99 else SetLogRootPath(LOGPATH); 100 101 Console.WriteLine("當前日誌儲存路徑:" + LOGPATH); 102 103 if (System.Configuration.ConfigurationManager.AppSettings.AllKeys.Contains("log_print_level")) 104 { 105 string log_print_level = System.Configuration.ConfigurationManager.AppSettings["log_print_level"].ToString(); 106 if (!Enum.TryParse(log_print_level, false, out LOG_PRINT_LEVEL)) 107 LOG_PRINT_LEVEL = LogLevel.DEBUG; 108 } 109 110 Console.WriteLine("當前日誌級別:" + LOG_PRINT_LEVEL); 111 112 if (System.Configuration.ConfigurationManager.AppSettings.AllKeys.Contains("log_print_file")) 113 { 114 string log_print_file = System.Configuration.ConfigurationManager.AppSettings["log_print_file"].ToString(); 115 if (!Boolean.TryParse(log_print_file, out LOG_PRINT_FILE)) 116 LOG_PRINT_FILE = true; 117 } 118 119 Console.WriteLine("當前日誌是否輸出檔案:" + LOG_PRINT_FILE); 120 121 if (System.Configuration.ConfigurationManager.AppSettings.AllKeys.Contains("log_print_file_buffer")) 122 { 123 string log_print_file_buffer = System.Configuration.ConfigurationManager.AppSettings["log_print_file_buffer"].ToString(); 124 if (!Boolean.TryParse(log_print_file_buffer, out LOG_PRINT_FILE_BUFFER)) 125 LOG_PRINT_FILE_BUFFER = true; 126 } 127 128 Console.WriteLine("當前日誌buff雙緩衝輸出檔案:" + LOG_PRINT_FILE_BUFFER); 129 130 if (System.Configuration.ConfigurationManager.AppSettings.AllKeys.Contains("log_print_console")) 131 { 132 string log_print_console = System.Configuration.ConfigurationManager.AppSettings["log_print_console"].ToString(); 133 if (!Boolean.TryParse(log_print_console, out LOG_PRINT_CONSOLE)) 134 LOG_PRINT_CONSOLE = true; 135 } 136 137 Console.WriteLine("當前日誌是否輸出控制檯:" + LOG_PRINT_CONSOLE); 138 139 if (System.Configuration.ConfigurationManager.AppSettings.AllKeys.Contains("logs_print_tackrace")) 140 { 141 string logs_print_tackrace = System.Configuration.ConfigurationManager.AppSettings["logs_print_tackrace"].ToString(); 142 if (!Boolean.TryParse(logs_print_tackrace, out LOG_PRINT_STACKTRACE)) 143 LOG_PRINT_STACKTRACE = false; 144 } 145 146 Console.WriteLine("當前日誌是否輸出棧楨:" + LOG_PRINT_STACKTRACE); 147 } 148 149 } 150 }
View Code

.config檔案AppSettings模組加入配置節點,可以設定日誌輸出引數

1     /// <para>預設是不列印棧楨的,因為比較耗時:如果需要請設定 LOGSTACKTRACE = true 或者 ↓↓↓</para>
2     /// <para>AppSettings 設定 log_print_stackrace         日誌是否輸出呼叫棧楨 true or false</para>
3     /// <para>AppSettings 設定 log_print_console           日誌是否輸出到控制檯 true or false</para>
4     /// <para>AppSettings 設定 log_print_level             日誌的等級,忽律大小寫 DEBUG INFO WARN ERROR</para>
5     /// <para>AppSettings 設定 log_print_path              日誌的檔名帶目錄,log/sz.log</para>
6     /// <para>AppSettings 設定 log_print_file              日誌是否輸出到檔案 true or false</para>
7     /// <para>AppSettings 設定 log_print_file_buffer       日誌雙緩衝輸出到檔案 true or false</para>

 日誌級別列舉獨立出來

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 
 8 /**
 9  * 
10  * @author 失足程式設計師
11  * @Blog http://www.cnblogs.com/ty408/
12  * @mail [email protected]
13  * @phone 13882122019
14  * 
15  */
16 namespace Net.Sz.Framework.Szlog
17 {
18 
19     /// <summary>
20     /// 日誌級別
21     /// </summary>
22     public enum LogLevel
23     {
24         /// <summary>
25         /// 完全不輸出任何日誌
26         /// </summary>
27         Null = 0,
28         /// <summary>
29         /// 輸出 DEBUG 以上級別
30         /// </summary>
31         DEBUG = 1,
32         /// <summary>
33         /// 輸出 INFO 以上級別
34         /// </summary>
35         INFO = 2,
36         /// <summary>
37         /// 輸出 WARN 以上級別
38         /// </summary>
39         WARN = 3,
40         /// <summary>
41         /// 輸出 ERROR 以上級別
42         /// </summary>
43         ERROR = 4
44     }
45 
46 }
View Code

 根據log4j使用習慣加入,日誌級別判斷減少呼叫和建立,

        public bool IsDebugEnabled()
        {
            return CommUtil.LOG_PRINT_LEVEL <= LogLevel.DEBUG;
        }

        public bool IsInfoEnabled()
        {
            return CommUtil.LOG_PRINT_LEVEL <= LogLevel.INFO;
        }

        public bool IsWarnEnabled()
        {
            return CommUtil.LOG_PRINT_LEVEL <= LogLevel.WARN;
        }

        public bool IsErrorEnabled()
        {
            return CommUtil.LOG_PRINT_LEVEL <= LogLevel.ERROR;
        }

 這個大家都懂的,也就是為了減少無用執行的;

本次優化還有一個重點之處在於日誌的構建呼叫執行緒執行,而不是寫入執行緒執行;

並且加入在構建日誌資訊的時候是否列印堆疊資訊,也就是呼叫棧楨情況;因測試這個比較耗時;所以預設不開放的;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="level"></param>
        /// <param name="msg"></param>
        /// <param name="exception"></param>
        /// <param name="f">棧楨深度</param>
        /// <returns></returns>
        string GetLogString(string level, Object msg, Exception exception, int f)
        {
            string tmp1 = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff: ");
            StringBuilder sb = new StringBuilder();

            sb.Append("[")
                .Append(tmp1)
                .Append(level)
                .Append(":");

            if (CommUtil.LOG_PRINT_STACKTRACE)
            {
                /*獲取堆疊資訊非常耗效能*/
                StackFrame frame = new StackTrace(f, true).GetFrame(0);
                sb.Append(frame.GetMethod().DeclaringType.FullName);
                sb.Append(".");
                sb.Append(frame.GetMethod().Name);
                sb.Append(".");
                sb.Append(frame.GetFileLineNumber());
            }
            sb.Append("] ");
            sb.AppendLine(msg.ToString());

            if (exception != null)
            {
                sb
                .Append(exception.GetType().FullName)
                .Append(": ")
                .AppendLine(exception.Message)
                .AppendLine(exception.StackTrace)
                .AppendLine("----------------------Exception--------------------------");
            }
            return sb.ToString();
        }
        StreamWriter wStream = null;
        FileStream fStream = null;

C#下面寫入檔案用流寫入;streamwriter類;提供了write方法,這個函式值輸入到基礎流;需要呼叫Flush();才是把流寫入檔案中;

那麼優化的雙緩衝方案就來了;迴圈寫入資料的時候,設定50次一個io,

注意:你的日誌量並不大還是一條日誌一個io,重點在於你日誌量很大的時候,間隔50條日誌一次檔案io

               while (msgs.Count > 0)
                {
                    CreateFile();
                    if (CommUtil.LOG_PRINT_FILE_BUFFER)
                    {
                        /*雙緩衝,減少磁碟IO*/
                        for (int i = 0; i < 50; i++)
                        {
                            String msg;
                            if (msgs.TryDequeue(out msg))
                            {
                                wStream.Write(msg);
                            }
                            else break;
                        }
                        /*輸入流到檔案*/
                        wStream.Flush();
                        fStream.Flush();
                    }
                    else
                    {
                        String msg;
                        if (msgs.TryDequeue(out msg))
                        {
                            /*輸入流到檔案*/
                            wStream.Write(msg);
                            wStream.Flush();
                            fStream.Flush();
                        }
                        else break;
                    }
                }        

本次優化檔案寫入條件加入檔案寫入指定檔案測試程式碼,但是不保證併發衝突,意圖在於除錯的時候,測試一些流程日誌

        /// <summary>
        /// 增加日誌
        /// </summary>
        /// <param name="level"></param>
        /// <param name="msg"></param>
        /// <param name="exception"></param>
        void AddLog(string level, Object msg, Exception exception)
        {
            string logmsg = GetLogString(level, msg, exception, 3);
            if (exception != null)
            {
                if (CommUtil.LOG_PRINT_FILE)
                {
                    /*處理如果有異常,需要把異常資訊列印到單獨的文字檔案*/
                    if (wfileerror == null)
                        lock (typeof(WriterFile))
                            if (wfileerror == null)
                                /*雙重判定單例模式,防止併發*/
                                wfileerror = new WriterFile(CommUtil.LOGPATH, "log-error-file", true);
                    wfileerror.Add(logmsg);
                }
            }
            if (CommUtil.LOG_PRINT_FILE)
            {
                /*處理到日誌檔案*/
                if (wfile == null)
                    lock (typeof(WriterFile))
                        if (wfile == null)
                            /*雙重判定單例模式,防止併發*/
                            wfile = new WriterFile(CommUtil.LOGPATH, "log-file", false);
                wfile.Add(logmsg);
            }
            if (CommUtil.LOG_PRINT_CONSOLE)
            {
                /*處理到控制檯*/
                if (wconsole == null)
                    lock (typeof(WriterFile))
                        if (wconsole == null)
                            /*雙重判定單例模式,防止併發*/
                            wconsole = new WriterConsole("log-console");
                wconsole.Add(logmsg);
            }
        }

日誌執行緒,需要是才會建立;如果沒有呼叫不會建立執行緒;

本次優化日誌執行緒分為日誌檔案執行緒,錯誤日誌檔案執行緒和日誌控制檯執行緒;

加入如果有exception,把當前日誌寫入error檔案進行備份,方便查詢exception;(並未有關閉操作,一定會寫)

本次在日誌操作加入每天一個檔案備份;

        /// <summary>
        /// 建立檔案以及備份檔案操作
        /// </summary>
        public void CreateFile()
        {
            String logPath = FileName;

            if (this.Error)
            {
                logPath += "_error.log";
            }

            if (File.Exists(logPath))
            {
                /*檢查檔案備份,每日一個備份*/
                DateTime dtime = File.GetLastWriteTime(logPath);

                string day1 = dtime.ToString("yyyy-MM-dd");
                string day2 = DateTime.Now.ToString("yyyy-MM-dd");
                /*獲取檔案的上一次寫入時間是否不是今天日期*/
                if (!day1.Equals(day2))
                {
                    Close();
                    wStream = null;
                    fStream = null;
                    /*備份*/
                    File.Move(logPath, logPath + "_" + day1 + ".log");
                }
            }

            if (fStream == null)
            {
                /*追加文字*/
                fStream = new FileStream(logPath, System.IO.FileMode.Append);
                /*重建流*/
                wStream = new System.IO.StreamWriter(fStream);
            }

        }
View Code

重點優化地方已經講解完畢;

測試

在雙緩衝輸出日誌的情況下效能測試;

 1 class Program
 2     {
 3 
 4         static SzLogger log = null;
 5 
 6         static void Main(string[] args)
 7         {
 8             CommUtil.LOG_PRINT_CONSOLE = false;
 9             CommUtil.LOG_PRINT_FILE = true;
10             //CommUtil.LOG_PRINT_FILE_BUFFER = false;
11             log = SzLogger.getLogger();
12             /*配置可以防在config裡面*/
13             CommUtil.LOG_PRINT_CONSOLE = true;
14             log.Debug("Debug");
15             /*修改列印級別,不會輸出info*/
16             CommUtil.LOG_PRINT_LEVEL = LogLevel.WARN;
17             log.Info("Info");
18             log.Warn("Warn");
19             log.Error("Error");
20 
21             /*取消控制檯列印*/
22             CommUtil.LOG_PRINT_CONSOLE = false;
23 
24             Console.WriteLine("準備好測試了請敲回車");
25             Console.ReadLine();
26 
27             long time = TimeUtil.CurrentTimeMillis();
28             for (int k = 0; k < 5; k++)
29             {
30                 /*5個執行緒*/
31                 new System.Threading.Thread(() =>
32                 {
33                     /*每個執行緒 10萬 條日誌*/
34                     for (int i = 0; i < 100000; i++)
35                     {
36                         Program.log.Error(i + " ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss我測ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss");
37                     }
38                 }).Start();
39             }
40             System.Threading.Thread.Sleep(20);
41             while (Program.log.Count > 0)
42             {
43 
44             }
45             Console.WriteLine("50萬條日誌併發寫入結束" + (TimeUtil.CurrentTimeMillis() - time));
46             Console.ReadLine();
47         }
48     }
View Code

輸出結果:

檔案大小:

以上是C#版本介紹結束;

Java

java版本和C#版本其實都是翻譯問題,思路都是一個思路;

採用NetBeans 8.2+ 工具,maven 專案管理;

java版本重點也還是在於日誌寫入思路;

採用流檔案寫入通道;之前也是對比了網上其他園友的寫入檔案方式來測試輸出,可能不是最優方案如果園友有更高效的方式請告知; 

BufferedWriter(new OutputStreamWriter(new FileOutputStream(file, true), "utf-8"));

 java中統樣採用50條日誌的磁碟io操作

 1                 while (!logs.isEmpty()) {
 2                     if (System.currentTimeMillis() - bigen > 1000) {
 3                         /*一秒鐘檢查一次檔案備份*/
 4                         bigen = System.currentTimeMillis();
 5                         createFileWriter();
 6                     }
 7                     if (CommUtil.LOG_PRINT_FILE_BUUFER) {
 8                         for (int i = 0; i < 50; i++
            
           

相關推薦

3秒鐘完成50併發日誌 檔案寫入

前言 目前本人從事 JAVA開發  之前講過《你的日誌元件記錄夠清晰嘛?--自己開發日誌元件 Logger》 日誌檔案,當你是羨慕java下面的log4j,列印日誌夠清晰,可以很清晰定位列印日誌所在檔案,行號等; 於是嘗試了重寫了日誌元件來模擬清晰列印; 序言 最近和群裡大佬們研究遊戲伺服器架構的時候,討論像

基於POIExcel匯入50+資料的基本寫法

基本思路如下 poi 基於xml解析(event user model ) 多執行緒批量插入 軟體環境 Springboot2.0 + MyBatis Mysql 5.7 + poi 基於xml解析(event user model ) package com.sunducation.wat

thinkphp 3.2.2 匯入 以及 5以上大檔案Excel表格匯入

一、首先說一下自己以前用的方式:以前是採用PHPoffice類+import.class.php檔案匯入。程式碼如下: 1.html程式碼: <a href="#" style="margin-right: 10px" id="leading_in" data-t

【py vs oracle_utl_file】oracle直接後臺匯出csv的速度大概2記錄,檔案5M,用時16秒,但是1600檔案4G,花了4小時

CREATE OR REPLACE PROCEDURE SQL_TO_CSV (  P_QUERY IN VARCHAR2, -- PLSQL文  P_DIR IN VARCHAR2, -- 匯出的檔案放置目錄  P_FILENAME IN VARCHAR2 --

phpmyadmin利用日誌檔案寫入一句話

前提: root許可權,已經進入了phpmyadmin後臺 1、首先進入phpmyadmin後臺,檢視genelog變數,更改general log和general log file引數,初始設定general log是OFF,我們將其改成ON;general log file我們將其改

Python實現日誌檔案寫入或者列印--類似於Java的Log4j

開發過Java的應該都知道Log4j的重要性,尤其是在開發測試中,能夠讓開發和測試人員方便找的bug,Python也有和Log4j相同功能的庫那就是logging庫,其功能非常強大,在開發測試中很方便,我是將其作為工具使用的,程式碼syslog.py如下: #!/usr/b

Laravel日誌檔案寫入失敗(permission denied)

用過Laravel的小夥伴一開始安裝完框架後可能都遇到過daily 日誌檔案寫入失敗的問題,接下來我們就來

年薪50的Web前端大牛,必須經歷的3個階段!

也許你現在還是剛接觸Web前端,也許你現在是個初級的Web前端開發工程師,相信每個人心中都希望自己可以達到年薪50萬! 今天小編就為各位分享Web前端起步階段、提升階段、成型階段都應該學習哪些知識?如何去學習這些知識?  “我自己是一名從事了5年web前端開發的老程式設計師

3豆瓣短評看《雷神3

哈嘍大家好,為了北方神的榮耀,我是雷神托爾!! 沒錯,這次的雷神3又轟轟烈烈地回來啦,開開心心地奉上一張真誠的車票。 迴歸正題,新片上映大家的反響還是非常熱烈的,這裡就單從廣大的豆瓣盆友的資料反饋進行一些個人淺析。截至11月14日為止,豆瓣已經有4w+的短評,用

3個普通人的致富案例,講述一個當下年賺50的創業機遇

這幾天我在很多平臺都看到了央視點名批評快手和火山的新聞,想必你也看到了! 移除點選此處新增圖片說明文字今天我把這個截圖發出來不是批評火山或快手為代表的短視訊APP,相反,對於這些APP的出現,我抱著敬畏的心態去面對!為啥?因為這是一個致富的通道!這是一條凡夫俗子可以魚躍龍門的

移動互聯網的機會-從零創業,半年凈賺50

tro 更多 白手起家 樂意 很難 賺錢 四六級 模式 同時 今天和大家聊聊微信創業,今天聊到的案例,比較有啟發性,它是一個新手改進別人的創業思路進行白手起家,充分的借用別人的資源來賺自己的錢,這很值得當前創業者去思考的。 白手起家單靠熱情蠻力是行不通的,要會借勢!什麽勢

unity中實現三個Logo圖片進行3秒鐘的若隱若現後互相切換Logo圖片

date += srp val logs ima 精靈 texture 透明 private List<Sprite> storeTexture; public void Start() { storeTextu

300.3重定向輸出流實現程序日誌

c幣 info fas tlb ipc 重定向 left aix pcf y3L興6d兜紋蛔6牢dhttp://t.docin.com/rjc54517 瓢oco躥J5a0道o悍4http://weibo.com/u/6366782838 2挪U皆汕敦62擁榔0漚ukht

3分鐘完成MongoDB2.6升級3.0

mongodb 2.6升級3.0 3分鐘完成MongoDB2.6升級3.0前言Part1:寫在最前自從3.0版本起,MongoDB支持了WT存儲引擎,這個引擎相對老的MMAPv1存儲引擎來講,具有更高的壓縮比,且支持文檔級並發控制。也正因為WT的優良特性,在MongoDB3.2版本起,WT存儲引擎作為

年薪50的Python架構師 不是夢

Python架構師 nginx redis 年薪50萬的Python架構師 不是夢 秒殺系統涉及主要技術有: Pytho Django 開發;Django web 頁面靜態化;Python Redis Sentinel(哨兵)集群開發;Redis 管道、事務實現對秒殺庫庫的管理;Redis隊

PHP簡單爬蟲 爬取免費代理ip 一

img mys i++ .com log mage top100 dai code 目標站:http://www.xicidaili.com/ 代碼: <?php require ‘lib/phpQuery.php‘; require ‘lib/QueryList.

十年阿裏資深架構師教你如何做到年薪 50 的程序員

帶來 邏輯 切入點 遊戲 實現 def 人生 比較 -s 寫在開篇 不管是開發、測試、運維,每個技術人員心裏都有一個成為技術大牛的夢,畢竟“夢想總是要有的,萬一實現了呢”!正是對技術夢的追求,促使我們不斷地努力和提升自己。 然而“夢想是美好的,現實卻是殘酷的”,很多同學在實

貓途鷹(tripadvisor.cn/)美國地區的酒店、景點、餐廳數據(82

auto dig name color 百度網盤 site add eva 數據格式 本文原創作者:數據超市(http://www.data-shop.net)本文原始鏈接:http://www.data-shop.net/2015/10/tripadvisor_cn_20

《一出好戲》講述人性,使用Python抓取貓眼近10評論並分析,一起揭秘“這出好戲”到底如何?

generate pro hand stk 同時 readlines 看電影 就是 msh 黃渤首次導演的電影《一出好戲》自8月10日在全國上映,至今已有10天,其主演陣容強大,相信許多觀眾也都是沖著明星們去的。目前《一出好戲》在貓眼上已經獲得近60萬個評價,評分為8.2

1300多數據30G論壇大數據優化實戰經驗小結

用戶反饋 文章 千萬 身體 分析器 png 監視 重點 border 最近由於某大型網站社區論壇運行效率比較低用戶反饋論壇有些卡需要對系統進行優化,論壇性能影響了公司的形象還有網站的流量,當然這也會影響到公司的收入,而且後期還需要長期維護網站的社區論壇服務。 1: