偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

基于線程池的線上服務(wù)性能優(yōu)化

開發(fā)
需求,總是自我技術(shù)提升,架構(gòu)升級優(yōu)化的動力源。

最近居家辦公。 正在發(fā)愁摸哪條魚的時候,產(chǎn)品突然在群里at了我一下,說到某某訂單曝光異常,讓配合看看。

仔細詢問了下訂單信息,乖乖,原來用的是6年前開發(fā)的一個功能,要知道這個功能自上線后基本很少用,不知道為什么現(xiàn)在開始用起來了,只能先放棄摸魚,先配合解決問題,畢竟要靠這個來吃飯的。

需求背景

在廣告中,經(jīng)常有這樣一種需求場景,需要將某個廣告定向投放給某一批指定用戶。即假設(shè)有一個adid,指定了投放用戶1和用戶2,那么只有在用戶1和用戶2的流量請求過來的時候,才會返回給adid,而其他用戶的流量,均不會返回該adid。

一般情況下,指定用戶多達幾百萬個甚至上千萬個,將這些用戶ID直接隨著廣告訂單推送過來,顯然不切實際,所以當時的設(shè)計方案是廣告主將包含有指定用戶ID的數(shù)據(jù)包上傳到廣告后臺,然后生成一個url,而該url則隨著廣告訂單推送過來。在引擎中,有個服務(wù)專門訂閱了廣告訂單消息,如果發(fā)現(xiàn)該廣告訂單是指定用戶投放,則將url指向的數(shù)據(jù)包中的數(shù)據(jù)獲取后,進行實時加載,這樣當其用戶ID流量過來的時候,就能匹配上該廣告。

初始設(shè)計

在開始本節(jié)之前,我們不妨先思考幾分鐘,如果讓你來實現(xiàn)這個功能,該如何實現(xiàn)呢?

好了,讓我們把時間調(diào)回到2016年年底,產(chǎn)品提出該需求的時間點。

當時看了該需求,還是蠻簡單的。為了便于內(nèi)容理解,將加載定向包的服務(wù)稱之為Retargeting。

Retargeting服務(wù)就兩個基本功能:

  • 訂閱廣告訂單消息隊列
  • 如果獲取到了有定向包的廣告訂單,則下載該定向包,然后獲取里面的數(shù)據(jù),建立倒排索引

是不是很簡單,代碼也非常好寫,下載定向包可以使用libcurl,也可以使用wget進行下載然后讀取文件加載到內(nèi)存,當時因為排期比較緊張,所以選擇了wget方式來實現(xiàn),因為數(shù)據(jù)量比較大,所以使用redis作為倒排索引的存儲媒介。

假設(shè)有一個廣告訂單我們稱之為ad,其包含一個定向包地址url,此時會做如下幾件事:

1、使用如下命令進行下載url所指向的定向包

auto cmd = "wget -t 3 -c -r -nd -P /data1/data/ –delete-after -np -A .txt http://url.txt";
auto fp = popen(cmd.str().c_str(), "r");
if (!fp) {
return;
}

2、以文件形式打開該包

// 獲取本地包地址,如/data1/data/url.txt
fp = fopen(path.c_str(), "r");
std::string id;
char buf[128] = {'\0'};
while (fgets(buf, 128, fp)) {
id = buf;
boost::replace_all(id, " ", "");
boost::replace_all(id, "\r", "");
boost::replace_all(id, "\n", "");
noost::replace_all(id, "\^M", "");
if (!id.empty()) {
ids.emplace_back(id);
}
}

3、Redis中建立倒排索引

for (auto item : ids) {
redis_client_->SAdd(item, adid);
}

好了,到了此處,Retargeting服務(wù)功能已經(jīng)基本都實現(xiàn)了。

在召回引擎中,當流量來了之后,會先以用戶ID為key,從redis中獲取指定投放該設(shè)備ID的adid,然后返回。

代碼編譯完后,在測試環(huán)境下了個單,推送,然后模擬請求,召回,完美。

問題初現(xiàn)

定向包功能,尤其是對于KA廣告主,是不屑使用的,畢竟他們財大氣粗,要的就是 ??腦白金?? 似的推廣效果,即 「只關(guān)注展示量,而不在乎是否有效果」 。奈何隨著國家政策的一步步調(diào)整,廣告行業(yè)都開始勒緊褲腰帶過日子,之前的大廣告主也開始關(guān)注投放效果了,畢竟 ??品效合一?? 嘛。于是,他們開始挖掘了一批用戶,在后臺開始投放,嘗試投放效果。隨著此類定向包訂單越來越多,之前實現(xiàn)的Retargeting也開始出現(xiàn)瓶頸了。。。

畢竟該功能使用不多,所以大部分情況下,產(chǎn)品或者運營提出問題的時候,都會找個借口搪塞回去。直到某一天,產(chǎn)品直接甩出來一張圖,說某個部門老大非??粗氐囊粋€廣告主的定向包投放曝光為0,并揚言當天解決不了,就通過其它渠道進行投放。。。

既然是部門老大都找過來了,那就不得不找下原因了,于是從訂單的url是否有效開始查起,定向包設(shè)備的有效覆蓋率,一直到整個訂單的推送時間,一切都正常,看來問題出在ReTargeting服務(wù)了,服務(wù)正常,加載也正常,無意間看了下消費進度,不看不知道,一看嚇一跳。才剛剛消費到昨天的訂單,也就是說當天要投放的訂單還沒開始加載,怪不得還沒有曝光,就這進度,有曝光才怪。

順便看了眼服務(wù)狀態(tài),乖乖,CPU占用這么低。。。

嘗試優(yōu)化

既然CPU占用這么低,那么有沒有可能從CPU占用這個角度進行優(yōu)化呢,提升CPU占用,提高服務(wù)處理能力,這樣就能加快其加載速度了。對于這種,一般稍微有點經(jīng)驗的,就會知道該怎么優(yōu)化,對,就是使用 ??多線程?? 。

既然決定使用多線程,那么就得徹底點,多線程處理訂單,在每個訂單中,又采用多線程進行數(shù)據(jù)加載和處理,我們暫且稱之為 ??M*N?? 多線程設(shè)計模型,如下:

在上圖中,采用多線程方式對Retargeting服務(wù)進行優(yōu)化,假設(shè)此時有m個定向包訂單,則會同時有m個線程進行處理,每個線程處理一個定向包訂單,看起來很完美,等等,會不會有其他問題呢?要不然一開始為什么就不這么設(shè)計呢?

大家知道,對于多線程程序, 「線程的執(zhí)行順序,完成時間是不可控的」 ,使用上述設(shè)計方案,如果多個線程 「同時處理多個不同的訂單,那么是沒有任何問題的」 ,但是,如果對于另外一種場景,該方案就不可行了,如下:

假設(shè)此時銷售創(chuàng)建了一個定向包訂單ad0,先推送上線。然后發(fā)現(xiàn)訂單有問題,所以隨即推送下線。那么此時消息隊列中有兩條消息,先是ad0的上線消息,然后是ad0的下線消息?;谏鲜龆嗑€程設(shè)計模型,假設(shè) 線程1執(zhí)行訂單上線,線程2執(zhí)行訂單下線 ,可能的結(jié)果就有如下幾種:

  • 先執(zhí)行上線訂單加載,再執(zhí)行下線訂單加載,此種情況符合預(yù)期
  • 下線訂單先完成,然后上線訂單完成,此種情況最終與我們期望的相反
  • 上線訂單和下線訂單同時執(zhí)行,且中間交叉進行,結(jié)果不可控

很明顯,該種方案不可行,盡管其最大可能地優(yōu)化了性能,但是得不到正確的結(jié)果,即使性能再好,又有啥用呢?

難道多線程設(shè)計模型真的不適用于我們這個服務(wù)嗎?

不妨調(diào)整下思路,在上述的方案分析中,多個線程同時處理多個訂單就會有問題,換句話說在M*N多線程設(shè)計模型中,正是因為M>1導(dǎo)致了結(jié)果不可預(yù)期,那么如果M=1呢?這樣會不會就會避免上述問題呢?

我們?nèi)匀灰陨鲜霭咐M行舉例,因為是單線程處理消息隊列,那么永遠都是先處理上線消息,然后再處理下線消息,這樣的結(jié)果永遠符合我們的預(yù)期。

既然方案已經(jīng)定了,那么就可以直接寫代碼了。在該方案中,我們用到了多線程進行處理,如果每次來了訂單消息都創(chuàng)建多個線程進行處理,處理完成后,銷毀線程。雖然也可以這么做,但多少對性能有所影響,所以干脆使用 ??線程池?? 來完成吧。base庫中有之前手擼的線程池,直接拿來使用。

for (auto did : ids) {
thread_pool.enqueue([did, adid, this]{
RedisClient client;
redis_client_pool_.Pop(&client);
if (client) {
client->SAdd(did, adid);
redis_client_pool_.Push(client);
}
});
}
}

編譯、部署、測試,一氣呵成,沒問題。開始上線,上線完成,看了下CPU利用率,完美:

數(shù)據(jù)說話,對比下優(yōu)化前后同一個訂單的處理時間:

性能提升接近30倍,符合預(yù)期。。。

需求,總是自我技術(shù)提升,架構(gòu)升級優(yōu)化的動力源。有時候,一個簡單的小優(yōu)化,就能達到事半功倍的效果。

責任編輯:張燕妮 來源: 高性能架構(gòu)探索
相關(guān)推薦

2023-03-08 18:43:50

GPU模型隔離

2011-07-19 10:46:49

Windows 7優(yōu)化

2012-12-24 09:55:15

JavaJava WebJava優(yōu)化

2010-01-08 09:43:23

SQL Server分Analysis Se

2021-05-19 08:04:11

ASP.Net服務(wù)性原則

2021-11-18 10:05:35

Java優(yōu)化QPS

2009-11-05 10:45:58

WCF服務(wù)

2025-09-08 11:20:00

2021-06-30 10:16:54

微服務(wù)架構(gòu)測試

2022-11-10 08:16:19

java性能服務(wù)性能

2017-09-26 14:56:57

MongoDBLBS服務(wù)性能

2024-10-07 08:37:32

線程池C#管理機制

2021-07-06 12:07:27

Go 服務(wù)性能

2012-04-26 14:08:52

2024-08-01 08:06:11

虛擬線程性能

2015-12-30 19:19:37

云存儲

2011-07-22 09:50:34

云服務(wù)云計算

2020-12-28 08:48:44

JS工具fastify

2020-12-14 15:40:59

Nodefastifyjs

2009-11-06 17:10:34

WCF服務(wù)性能計數(shù)器
點贊
收藏

51CTO技術(shù)棧公眾號