① 程序員被納入「新生代農民工」,碼農為何會被官方定義為「新生代農民工」
01 什麼是新生代農民工「碼農」就是我們常說的程序員,因為靠寫代碼衛生,而且收入低,要長時間面對電腦,所以就自嘲為「碼農」。
我們先來看看「新生代農民工」的定義:
出生於20世紀80年代以後,年齡在16歲以上,在異地以非農就業為主的農業戶籍人口。
具體點來說,他們是「集中於勞動密集型行業,從事信息傳輸、軟體和信息技術服務業的打工人」。
所以如果單從這個描述來說的話,從事軟體和信息服務的程序員們很顯然就是「新生代農民工」中的一員。
但如果你看仔細點的話,你就會發現要滿足「新生代農民工」,條件有兩個:
1.在外地從事非農業行業;
2.農村戶口。
因此嚴格來說,標準的「碼農」前提要有「農村戶籍」,「城鎮戶口的碼農」是不屬於「新生代農民工」范疇的。
就光看這幾點,哪個跟農民工兄弟不是一樣的?
② 如何搭建億級並發的系統架構
想設計億萬級高並發架構,你要先知道高並發是什麼?
面對流量高峰,不同的企業是如何通過技術手段解決高並發難題的呢?
0、引言
軟體系統有三個追求:高性能、高並發、高可用,俗稱三高。三者既有區別也有聯系,門門道道很多,全面討論需要三天三夜,本篇討論高並發。
高並發(High Concurrency)。並發是操作系統領域的一個概念,指的是一段時間內多任務流交替執行的現象,後來這個概念被泛化,高並發用來指大流量、高請求的業務情景,比如春運搶票,電商雙十一,秒殺大促等場景。
很多程序員每天忙著搬磚,平時接觸不到高並發,哪天受不了跑去面試,還常常會被面試官犀利的高並發問題直接KO,其實吧,高並發系統也不高深,我保證任何一個智商在線的看過這篇文章後,都能戰勝恐懼,重拾生活的信心。
本文先介紹高並發系統的度量指標,然後講述高並發系統的設計思路,再梳理高並發的關鍵技術,最後結合作者的經驗做一些延伸探討。
1、高並發的度量指標
既然是高並發系統,那並發一定要高,不然就名不副實。並發的指標一般有QPS、TPS、IOPS,這幾個指標都是可歸為系統吞吐率,QPS越高系統能hold住的請求數越多,但光關注這幾個指標不夠,我們還需要關注RT,即響應時間,也就是從發出request到收到response的時延,這個指標跟吞吐往往是此消彼長的,我們追求的是一定時延下的高吞吐。
比如有100萬次請求,99萬次請求都在10毫秒內響應,其他次數10秒才響應,平均時延不高,但時延高的用戶受不了,所以,就有了TP90/TP99指標,這個指標不是求平均,而是把時延從小到大排序,取排名90%/99%的時延,這個指標越大,對慢請求越敏感。
除此之外,有時候,我們也會關注可用性指標,這可歸到穩定性。
一般而言,用戶感知友好的高並發系統,時延應該控制在250毫秒以內。
什麼樣的系統才能稱為高並發?這個不好回答,因為它取決於系統或者業務的類型。不過我可以告訴你一些眾所周知的指標,這樣能幫助你下次在跟人扯淡的時候稍微靠點兒譜,不至於貽笑大方。
通常,資料庫單機每秒也就能抗住幾千這個量級,而做邏輯處理的服務單台每秒抗幾萬、甚至幾十萬都有可能,而消息隊列等中間件單機每秒處理個幾萬沒問題,所以我們經常聽到每秒處理數百萬、數千萬的消息中間件集群,而像阿某的API網關,每日百億請求也有可能。
2、高並發的設計思路
高並發的設計思路有兩個方向:
垂直方向擴展,也叫豎向擴展
水平方向擴展,也叫橫向擴展
垂直方向:提升單機能力
提升單機處理能力又可分為硬體和軟體兩個方面:
硬體方向,很好理解,花錢升級機器,更多核更高主頻更大存儲空間更多帶寬
軟體方向,包括用各快的數據結構,改進架構,應用多線程、協程,以及上性能優化各種手段,但這玩意兒天花板低,就像提升個人產出一樣,996、007、最多24 X 7。
水平方向:分布式集群
為了解決分布式系統的復雜性問題,一般會用到架構分層和服務拆分,通過分層做隔離,通過微服務解耦。
這個理論上沒有上限,只要做好層次和服務劃分,加機器擴容就能滿足需求,但實際上並非如此,一方面分布式會增加系統復雜性,另一方面集群規模上去之後,也會引入一堆AIOps、服務發現、服務治理的新問題。
因為垂直向的限制,所以,我們通常更關注水平擴展,高並發系統的實施也主要圍繞水平方向展開。
3、高並發的關鍵技術
玩具式的網路服務程序,用戶可以直連伺服器,甚至不需要資料庫,直接寫磁碟文件。但春運購票系統顯然不能這么做,它肯定扛不住這個壓力,那一般的高並發系統是怎麼做呢?比如某寶這樣的正經系統是怎麼處理高並發的呢?
其實大的思路都差不多,層次劃分 + 功能劃分。可以把層次劃分理解為水平方向的劃分,而功能劃分理解為垂直方向的劃分。
首先,用戶不能直連伺服器,要做分布式就要解決「分」的問題,有多個服務實例就需要做負載均衡,有不同服務類型就需要服務發現。
集群化:負載均衡
負載均衡就是把負載(request)均衡分配到不同的服務實例,利用集群的能力去對抗高並發,負載均衡是服務集群化的實施要素,它分3種:
DNS負載均衡,客戶端通過URL發起網路服務請求的時候,會去DNS伺服器做域名解釋,DNS會按一定的策略(比如就近策略)把URL轉換成IP地址,同一個URL會被解釋成不同的IP地址,這便是DNS負載均衡,它是一種粗粒度的負載均衡,它只用URL前半部分,因為DNS負載均衡一般採用就近原則,所以通常能降低時延,但DNS有cache,所以也會更新不及時的問題。
硬體負載均衡,通過布置特殊的負載均衡設備到機房做負載均衡,比如F5,這種設備貴,性能高,可以支撐每秒百萬並發,還能做一些安全防護,比如防火牆。
軟體負載均衡,根據工作在ISO 7層網路模型的層次,可分為四層負載均衡(比如章文嵩博士的LVS)和七層負載均衡(NGINX),軟體負載均衡配置靈活,擴展性強,阿某雲的SLB作為服務對外售賣,Nginx可以對URL的後半部做解釋承擔API網關的職責。
所以,完整的負載均衡鏈路是 client <-> DNS負載均衡 -> F5 -> LVS/SLB -> NGINX
不管選擇哪種LB策略,或者組合LB策略,邏輯上,我們都可以視為負載均衡層,通過添加負載均衡層,我們將負載均勻分散到了後面的服務集群,具備基礎的高並發能力,但這只是萬里長征第一步。
資料庫層面:分庫分表+讀寫分離
前面通過負載均衡解決了無狀態服務的水平擴展問題,但我們的系統不全是無狀態的,後面通常還有有狀態的資料庫,所以解決了前面的問題,存儲有可能成為系統的瓶頸,我們需要對有狀態存儲做分片路由。
資料庫的單機QPS一般不高,也就幾千,顯然滿足不了高並發的要求。
所以,我們需要做分庫分表 + 讀寫分離。
就是把一個庫分成多個庫,部署在多個資料庫服務上,主庫承載寫請求,從庫承載讀請求。從庫可以掛載多個,因為很多場景寫的請求遠少於讀的請求,這樣就把對單個庫的壓力降下來了。
如果寫的請求上升就繼續分庫分表,如果讀的請求上升就掛更多的從庫,但資料庫天生不是很適合高並發,而且資料庫對機器配置的要求一般很高,導致單位服務成本高,所以,這樣加機器抗壓力成本太高,還得另外想招。
讀多寫少:緩存
緩存的理論依據是局部性原理。
一般系統的寫入請求遠少於讀請求,針對寫少讀多的場景,很適合引入緩存集群。
在寫資料庫的時候同時寫一份數據到緩存集群里,然後用緩存集群來承載大部分的讀請求,因為緩存集群很容易做到高性能,所以,這樣的話,通過緩存集群,就可以用更少的機器資源承載更高的並發。
緩存的命中率一般能做到很高,而且速度很快,處理能力也強(單機很容易做到幾萬並發),是理想的解決方案。
CDN本質上就是緩存,被用戶大量訪問的靜態資源緩存在CDN中是目前的通用做法。
緩存也有很多需要謹慎處理的問題:
一致性問題:(a)更新db成功+更新cache失敗 -> 不一致 (b)更新db失敗+更新cache成功 -> 不一致 ©更新db成功+淘汰緩存失敗 -> 不一致
緩存穿透:查詢一定不存在的數據,會穿透緩存直接壓到資料庫,從而導致緩存失去作用,如果有人利用這個漏洞,大量查詢一定不存在的數據,會對資料庫造成壓力,甚至打掛資料庫。解決方案:布隆過濾器 或者 簡單的方案,查詢不存在的key,也把空結果寫入緩存(設置較短的過期淘汰時間),從而降低命失
緩存雪崩:如果大量緩存在一個時刻同時失效,則請求會轉到DB,則對DB形成壓迫,導致雪崩。簡單的解決方案是為緩存失效時間添加隨機值,降低同一時間點失效淘汰緩存數,避免集體失效事件發生
但緩存是針對讀,如果寫的壓力很大,怎麼辦?
高寫入:消息中間件
同理,通過跟主庫加機器,耗費的機器資源是很大的,這個就是資料庫系統的特點所決定的。
相同的資源下,資料庫系統太重太復雜,所以並發承載能力就在幾千/s的量級,所以此時你需要引入別的一些技術。
比如說消息中間件技術,也就是MQ集群,它是非常好的做寫請求非同步化處理,實現削峰填谷的效果。
消息隊列能做解耦,在只需要最終一致性的場景下,很適合用來配合做流控。
假如說,每秒是1萬次寫請求,其中比如5千次請求是必須請求過來立馬寫入資料庫中的,但是另外5千次寫請求是可以允許非同步化等待個幾十秒,甚至幾分鍾後才落入資料庫內的。
那麼此時完全可以引入消息中間件集群,把允許非同步化的每秒5千次請求寫入MQ,然後基於MQ做一個削峰填谷。比如就以平穩的1000/s的速度消費出來然後落入資料庫中即可,此時就會大幅度降低資料庫的寫入壓力。
業界有很多著名的消息中間件,比如ZeroMQ,rabbitMQ,kafka等。
消息隊列本身也跟緩存系統一樣,可以用很少的資源支撐很高的並發請求,用它來支撐部分允許非同步化的高並發寫入是很合適的,比使用資料庫直接支撐那部分高並發請求要減少很多的機器使用量。
避免擠兌:流控
再強大的系統,也怕流量短事件內集中爆發,就像銀行怕擠兌一樣,所以,高並發另一個必不可少的模塊就是流控。
流控的關鍵是流控演算法,有4種常見的流控演算法。
計數器演算法(固定窗口):計數器演算法是使用計數器在周期內累加訪問次數,當達到設定的限流值時,觸發限流策略,下一個周期開始時,進行清零,重新計數,實現簡單。計數器演算法方式限流對於周期比較長的限流,存在很大的弊端,有嚴重的臨界問題。
滑動窗口演算法:將時間周期分為N個小周期,分別記錄每個小周期內訪問次數,並且根據時間滑動刪除過期的小周期,當滑動窗口的格子劃分的越多,那麼滑動窗口的滾動就越平滑,限流的統計就會越精確。此演算法可以很好的解決固定窗口演算法的臨界問題。
漏桶演算法:訪問請求到達時直接放入漏桶,如當前容量已達到上限(限流值),則進行丟棄(觸發限流策略)。漏桶以固定的速率進行釋放訪問請求(即請求通過),直到漏桶為空。分布式環境下實施難度高。
令牌桶演算法:程序以r(r=時間周期/限流值)的速度向令牌桶中增加令牌,直到令牌桶滿,請求到達時向令牌桶請求令牌,如獲取到令牌則通過請求,否則觸發限流策略。分布式環境下實施難度高。
4、高並發的實踐經驗
接入-邏輯-存儲是經典的互聯網後端分層,但隨著業務規模的提高,邏輯層的復雜度也上升了,所以,針對邏輯層的架構設計也出現很多新的技術和思路,常見的做法包括系統拆分,微服務。
除此之外,也有很多業界的優秀實踐,包括某信伺服器通過協程(無侵入,已開源libco)改造,極大的提高了系統的並發度和穩定性,另外,緩存預熱,預計算,批量讀寫(減少IO),池技術等也廣泛應用在實踐中,有效的提升了系統並發能力。
為了提升並發能力,邏輯後端對請求的處理,一般會用到生產者-消費者多線程模型,即I/O線程負責網路IO,協議編解碼,網路位元組流被解碼後產生的協議對象,會被包裝成task投入到task queue,然後worker線程會從該隊列取出task執行,有些系統會用多進程而非多線程,通過共享存儲,維護2個方向的shm queue,一個input q,一個output q,為了提高並發度,有時候會引入協程,協程是用戶線程態的多執行流,它的切換成本更低,通常有更好的調度效率。
另外,構建漏斗型業務或者系統,從客戶端請求到接入層,到邏輯層,到DB層,層層遞減,過濾掉請求,Fail Fast(盡早發現盡早過濾),嘴大屁眼小,哈哈。
漏斗型系統不僅僅是一個技術模型,它也可以是一個產品思維,配合產品的用戶分流,邏輯分離,可以構建全方位的立體模型。
5、小結
莫讓浮雲遮望眼,除去繁華識真顏。我們不能掌握了大方案,吹完了牛皮,而忽視了編程最本質的東西,掌握最基本最核心的編程能力,比如數據架構和演算法,設計,慣用法,培養技術的審美,也是很重要的,既要致高遠,又要盡精微。
③ 31歲程序員熬夜時忽然眼一黑,醫生是怎麼說的
熬夜已經成為了是一種常見現像,對於年輕人來說,總是認為還年輕身體好,所以覺得熬夜並沒有什麼影響,其實,熬夜的危害是非常的大,不僅會傷肝傷腎,長期以往,身體就會慢慢的出現疾病。經常熬夜的人,時間久了通常都會有些不舒服,可能有些症狀,我們並沒有重視,但是當我們的身體發出一些嚴重的求救信號時,說明已經很嚴重了。
醫生提醒,季節變換,天氣逐漸變冷,也是視網膜動脈阻塞高發期,對於三高人群,一定要有規律的作息,要合理的飲食,同時戒煙戒酒,最好是定期的體檢。
④ 程序員怎樣鍛煉好身體
作為一名程序員,很久以前就關注了這個問題,但最近身邊一些人和事有了些切身體驗,然後對它進行一些思考。首先,對於程序員或者辦公室人員來說,由於長時間的伏案寫字再加上不正常的體態,會產生以下四個最常見的健康問題:
1.肩頸疼痛
2.腰背疼痛
3.肥胖
4.精力差,三高
出現問題的原因有很多,簡單來說身體一直處於亞健康狀態。其中主要原因是
熬夜
相信很多程序員都有熬夜的習慣,我之前天天到深夜1點才睡。很多程序員將熬夜變成了生活習慣,大部分的原因一方面是被義務教育坑害了,不得不熬夜和人拼時間,另一方面因為網路的發達使得更多的年輕人忘記了時間的概念。作為程序員,內心就形成了「程序員只有在晚上效率才高」的理念。甚至很多公司都提倡這樣的工作方式,晚上天天加班,早上晚點上班。但這種方式對你的健康傷害是最大的。因為人體最大的補品不是什麼高昂的食材,而是睡眠,睡眠能治癒的病比吃葯有效,並且人體造血的時間一般在凌晨一點。因此,我建議熬夜的朋友把睡覺時間提前到起碼11點之前,把起床時間也提前,這樣睡眠時間長一樣,這一天會過得更精神爽利更事半功倍。
久坐
很多人身體跟著酸疼,骨頭各種問題,最大原因有些程序員在電腦面前一坐就是一天,中間除了吃飯上廁所外,基本不起來動動。這是非常不好的習慣,時間久了,很容易得肩周炎、頸椎病,到時候後悔就晚了。我們可以在中午吃飯時間抽空來散步,有助於消化,也緩解工作壓力。利用手機App提醒功能,提醒自己休息,定時站起來拉伸運動一下。如果需要的話,做一些眼保健操。我自己經歷來說,我會經常早上做瑜伽,會對身體有很大的改善。
缺乏鍛煉
很多程序員會反駁我說,哪有這種美國時間做鍛煉。其實我們應該問一下我們自己,我們不幹活的時間都做了什麼,那百分之九十的人都說是在低頭玩手機,手機上有什麼國家大事需要你一有時間就處理么?其實沒有!我們只想簡單的獲取一些精神娛樂,來撫平我們生活和工作的壓力。那麼我們抽出一些時間來鍛煉鍛煉又有何妨呢。
平衡生活和工作的關系:剛工作那會,就一個人其實這個問題並不突出,隨著年齡增長,如何平衡好我有一些自己的想法。有的人是工作狂,有的人對工作不上心,我覺得都不合適。工作狂我已經見過不止一例身體最後出現嚴重問題的很多。最後還是花錢養身體。
談到運動,我覺得世界上最好的運動就是自己能堅持下來的運動,譬如我愛跑步,我每天早上會花時間跑步。我辦公室在10樓,我堅持不做電梯,每天上下爬個4,5次。爬第一次會覺得很累,上氣不接下氣,但每天去爬,最後你會發現自己氣都不喘一下。運動只要去堅持,肯定會有收獲。
最後希望大家多多保重。
⑤ 住養老院39歲程序員已出院,程序員發生職業病的概率更高嗎
住養老院39歲程序員已經出院,程序員發生職業病的概率非常高,理由如下:
第一:程序員的工作時間不固定,工作時間很長程序員的工作時間是非常不固定的,因為沒有人能夠預料系統或者程序到底什麼時候出bug,到底什麼時候會崩潰。所以說就算是半夜的時候,程序員也必須要馬上工作解決問題。特別是在互聯網時代,一旦系統崩潰,那麼可能就會影響到數億人的生活。所以說程序員的工作時間往往是比較久的。
第四:程序員容易有三高程序員中大部分的人都是宅男,宅男不願意社交,大部分時間都是在工作或者待在家裡,就連吃飯基本上也都是外賣。基本上不會主動去運動,所以說這樣的人時間久了就會出現肥胖,而肥胖就是造成三高的罪魁禍首之一。對於身體的傷害是非常大的,再加上程序員吃外賣都是高油、高鹽的食物,時間久了也會損傷腸道,引起一系列的健康問題。所以說程序員確實很容易患上職業病。
⑥ 程序員應該注意哪些身體健康他們容易患什麼職業病
沒吃過泡麵不算程序員,沒加過班的不是程序員,久而久之各種健康問題就來了,當然小編也知道要要因人而異,不同的職業會引發不同的毛病。據國外的一項調查表明,頭發的變化與相應人群在年齡,性別甚至職業上都有明顯的特徵,程序員的脫發現象,很有可能是因為長時間工作壓力大,長期加班和睡眠障礙,作息混亂等等原因造成的亞健康。
如何很快的淘汰一個人,是讓他太忙,忙到沒有時間休息,沒有時間創造思維,沒有時間學習,才為可怕。所以,請擁有好心態,技術學不完,時間是自己的。有些關於身體上的一些疾病自己要注重,畢竟身體是自己的,別人無法與你一起承受疼痛。