
??????教程全知識點簡介:1.APScheduler任務調度涵蓋安裝配置、使用方式、調度器Scheduler、執(zhí)行器executors、觸發(fā)器Trigger等核心組件。2. RPC遠程過程調用包括RPC概念、背景用途、優(yōu)缺點分析。3. Protocol Buffers數(shù)據(jù)序列化涉及文檔結構、注釋語法、數(shù)據(jù)類型、枚舉類型、消息類型(字段編號、字段規(guī)則、嵌套類型、保留字段、默認值)。4. 客戶端開發(fā)包含頭條首頁新聞推薦接口編寫。5. 即時通訊技術涵蓋需求場景、傳統(tǒng)推送實現(xiàn)、Socket.IO(Python服務器端開發(fā)、事件處理)。6. Elasticsearch搜索引擎包括簡介原理、倒排索引、分析器、相關性排序、集群概念、IK中文分析器、索引類型、文檔操作(索引文檔、獲取文檔、判斷存在、更新刪除)、Logstash數(shù)據(jù)導入、查詢(基本查詢、高級查詢)、全文檢索實現(xiàn)、Python客戶端使用、聯(lián)想提示(拼寫糾錯、自動補全)。7. 單元測試涵蓋測試分類、基本寫法、測試必要性。8. 服務器部署包括Gunicorn、Supervisor配置管理。9. 項目開發(fā)流程涉及產(chǎn)品介紹、原型圖UI圖、技術架構、開發(fā)環(huán)境(ToutiaoWeb虛擬機、Pycharm遠程開發(fā))。10. 數(shù)據(jù)庫技術包含ORM理解、SQLAlchemy映射構建、數(shù)據(jù)庫連接設置、模型類字段選項。11. 分布式系統(tǒng)涵蓋分布式ID方案選擇、Twitter Snowflake算法(64位ID劃分、最大取值計算、移位偏移計算、序號循環(huán)掩碼、時間戳處理)。12. Redis數(shù)據(jù)庫包括Redis持久化機制。13. Git工作流涵蓋Gitflow工作流(工作方式、歷史分支、功能分支、發(fā)布分支、維護分支)、調試方法。14. 身份認證技術包含JWT、JWS、JWE概念、Python庫使用、項目封裝實施方案。15. 對象存儲涉及OSS對象存儲、七牛云存儲服務。16. 緩存系統(tǒng)包括緩存架構、緩存數(shù)據(jù)保存方式、緩存有效期TTL、緩存淘汰策略、緩存問題(緩存穿透、緩存雪崩)、頭條項目緩存設計(User Cache、Article Cache、Announcement Cache)、持久存儲設計(閱讀歷史、搜索歷史、統(tǒng)計數(shù)據(jù))。

????倉庫code.zip ??直接-->:???https://gitee.com/yinuo112/Backend/blob/master/Python/嘿馬頭條項目從到完整開發(fā)教程/note.md ???????
? 本教程項目亮點
?? 知識體系完整:覆蓋從基礎原理、核心方法到高階應用的全流程內容
?? 全技術鏈覆蓋:完整前后端技術棧,涵蓋開發(fā)必備技能
?? 從零到實戰(zhàn):適合 0 基礎入門到提升,循序漸進掌握核心能力
?? 豐富文檔與代碼示例:涵蓋多種場景,可運行、可復用
?? 工作與學習雙參考:不僅適合系統(tǒng)化學習,更可作為日常開發(fā)中的查閱手冊
?? 模塊化知識結構:按知識點分章節(jié),便于快速定位和復習
?? 長期可用的技術積累:不止一次學習,而是能伴隨工作與項目長期參考
??????全教程總章節(jié)


??????本篇主要內容
RPC
編寫客戶端
在toutiao-backend/common/rpc目錄下新建client.py
import grpc
import reco_pb2
import reco_pb2_grpc
import time
def feed_articles(stub):
# 構建rpc調用的調用參數(shù)
user_request = reco_pb2.UserRequest()
user_request.user_id = '1'
user_request.channel_id = 1
user_request.article_num = 10
user_request.time_stamp = round(time.time()*1000)
# 通過stub進行方法調用,并接收調用返回值
ret = stub.user_recommend(user_request)
print('ret={}'.format(ret))
def run():
"""
rpc客戶端調用的方法
"""
# 使用with語句連接rpc服務器
with grpc.insecure_channel('127.0.0.1:8888') as channel:
# 創(chuàng)建調用rpc遠端服務的輔助對象stub
stub = reco_pb2_grpc.UserRecommendStub(channel)
# 通過stub進行rpc調用
feed_articles(stub)
if __name__ == '__main__':
run()
頭條首頁新聞推薦接口編寫
在toutiao-backend/toutiao/resources/news/article.py中編寫
from rpc import reco_pb2, reco_pb2_grpc
class ArticleListResource(Resource):
"""
獲取推薦文章列表數(shù)據(jù)
"""
def _feed_articles(self, channel_id, timestamp, feed_count):
"""
獲取推薦文章
:param channel_id: 頻道id
:param feed_count: 推薦數(shù)量
:param timestamp: 時間戳
:return: [{article_id, trace_params}, ...], timestamp
"""
user_request = reco_pb2.UserRequest()
user_request.user_id = g.user_id or 'annoy'
user_request.channel_id = channel_id
user_request.article_num = feed_count
user_request.time_stamp = round(time.time() * 1000)
stub = reco_pb2_grpc.UserRecommendStub(current_app.rpc_reco)
ret = stub.user_recommend(user_request)
return ret.recommends, ret.time_stamp
def get(self):
"""
獲取文章列表
"""
qs_parser = RequestParser()
qs_parser.add_argument('channel_id', type=parser.channel_id, required=True, location='args')
qs_parser.add_argument('timestamp', type=inputs.positive, required=True, location='args')
args = qs_parser.parse_args()
channel_id = args.channel_id
timestamp = args.timestamp
per_page = constants.DEFAULT_ARTICLE_PER_PAGE_MIN
try:
feed_time = time.strftime('%Y-%m-%dT%H:%M:%S', time.localtime(time.time()))
except Exception:
return {'message': 'timestamp param error'}, 400
results = []
# 獲取推薦文章列表
feeds, pre_timestamp = self._feed_articles(channel_id, timestamp, per_page)
# 查詢文章
for feed in feeds:
article = cache_article.ArticleInfoCache(feed.article_id).get()
if article:
article['pubdate'] = feed_time
article['trace'] = {
'click': feed.track.click,
'collect': feed.track.collect,
'share': feed.track.share,
'read': feed.track.read
}
results.append(article)
return {'pre_timestamp': pre_timestamp, 'results': results}
RPC
即時通訊簡介
即時通訊(Instant Messaging)是一種基于互聯(lián)網(wǎng)的即時交流消息的業(yè)務。
類型:
-
在線push
適用:web頁面 和 App
-
自己構建IM服務器
- 使用WebSocket
- 采用成熟的框架方案Socket.IO
- 對于App還可自己封裝socket
使用第三方IM服務商提供的服務
-
離線push
- 適用:App
- 對于iOS,使用APNs
- 對于andorid,使用FCM(國外)或第三方IM服務商提供的服務
提供第三方IM服務的服務商有:
- 網(wǎng)易云信
- 融云
- 環(huán)信
- LeanCloud
下面只針對 「在線推送」 的自建方案來展開講解。
需求場景
服務端需要主動推送消息給客戶端,例如
- 用戶下了訂order單,需要在運營管理后臺向運營人員推送新訂order單通知
- 用戶A關注了用戶B,系統(tǒng)需要向用戶B推送提示消息
- 即時聊天
傳統(tǒng)的推送實現(xiàn)
HTTP/1.x 不支持服務器主動推送,只能在客戶端發(fā)起請求后做出回應。 (HTTP/2支持服務器主動推送,但HTTP/2 還未全面實施)
- 輪詢
輪詢是在特定的的時間間隔(如每1秒),由客戶端對服務器發(fā)出HTTP請求,了解服務器有沒有新的信息,然后由服務器告知有無新數(shù)據(jù)或返回最新的數(shù)據(jù)給客戶端。
缺點:
- 效率低下,浪費資源
必須不停連接,或者連接始終打開,但傳輸HTTP請求,然而HTTP請求可能包含較長的頭部,其中真正有效的數(shù)據(jù)可能只是很小的一部分,顯然這樣會浪費很多的帶寬等資源。
-
Comet (基于長連接)
- 長輪詢 長輪詢是在打開一條連接以后保持,等待服務器推送來數(shù)據(jù)再關閉的方式。
- iframe流 iframe流方式是在頁面中插入一個隱藏的iframe,利用其src屬性在服務器和客戶端之間創(chuàng)建一條長鏈接,服務器向iframe傳輸數(shù)據(jù)(通常是HTML,內有負責插入信息的javascript),來實時更新頁面。
缺點:
依然需要反復發(fā)出請求,而且長連接也會消耗服務器資源。
WebSocket
HTML5定義了WebSocket協(xié)議,能更好的節(jié)省服務器資源和帶寬,并且能夠更實時地進行通訊。
在2008年誕生,2011年成為國際標準。
現(xiàn)在基本所有瀏覽器都已經(jīng)支持了。
WebSocket是一種在單個TCP連接上進行全雙工通信的協(xié)議。在WebSocket API中,瀏覽器和服務器只需要完成一次握手(不是指建立TCP連接的那個三次握手,是指在建立TCP連接后傳輸一次握手數(shù)據(jù)),兩者之間就直接可以創(chuàng)建持久性的連接,并進行雙向數(shù)據(jù)傳輸。

Websocket使用ws或wss的統(tǒng)一資源標志符,類似于HTTPS,其中wss表示在TLS之上的Websocket。如:
ws://example.com/wsapi
wss://secure.example.com/
Websocket使用和 HTTP 相同的 TCP 端口,可以繞過大多數(shù)防火墻的限制。默認情況下,Websocket協(xié)議使用80端口;運行在TLS之上時,默認使用443端口。

握手協(xié)議
WebSocket 是獨立的、創(chuàng)建在 TCP 上的協(xié)議。 報文
Websocket 通過 HTTP/1.1 協(xié)議的101狀態(tài)碼進行握手。
為了創(chuàng)建Websocket連接,需要通過瀏覽器發(fā)出請求,之后服務器進行回應,這個過程通常稱為“握手”(handshaking)。
一個典型的Websocket握手請求如下:
客戶端請求
GET / HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: example.com
Origin: http://example.com
Sec-WebSocket-Key: sN9cRrP/n9NdMgdcy2VJFQ==
Sec-WebSocket-Version: 13
服務器回應
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: fFBooB7FAkLlXgRSz0BT3v4hq5s=
Sec-WebSocket-Location: ws://example.com/
- Connection必須設置Upgrade,表示客戶端希望連接升級。
- Upgrade字段必須設置Websocket,表示希望升級到Websocket協(xié)議。
- Sec-WebSocket-Key是隨機的字符串,服務器端會用這些數(shù)據(jù)來構造出一個SHA-1的信息摘要。把“Sec-WebSocket-Key”加上一個特殊字符串“258EAFA5-E914-47DA-95CA-C5AB0DC85B11”,然后計算SHA-1摘要,之后進行BASE-64編碼,將結果做為“Sec-WebSocket-Accept”頭的值,返回給客戶端。如此操作,可以盡量避免普通HTTP請求被誤認為Websocket協(xié)議。
- Sec-WebSocket-Version 表示支持的Websocket版本。RFC6455要求使用的版本是13,之前草案的版本均應當棄用。
- Origin字段是可選的,通常用來表示在瀏覽器中發(fā)起此Websocket連接所在的頁面,類似于Referer。但是,與Referer不同的是,Origin只包含了協(xié)議和主機名稱。
- 其他一些定義在HTTP協(xié)議中的字段,如Cookie等,也可以在Websocket中使用。
優(yōu)點
- 較少的控制開銷。在連接創(chuàng)建后,服務器和客戶端之間交換數(shù)據(jù)時,用于協(xié)議控制的數(shù)據(jù)包頭部相對較小。在不包含擴展的情況下,對于服務器到客戶端的內容,此頭部大小只有2至10字節(jié)(和數(shù)據(jù)包長度有關);對于客戶端到服務器的內容,此頭部還需要加上額外的4字節(jié)的掩碼。相對于HTTP請求每次都要攜帶完整的頭部,此項開銷顯著減少了。
- 更強的實時性。由于協(xié)議是全雙工的,所以服務器可以隨時主動給客戶端下發(fā)數(shù)據(jù)。相對于HTTP請求需要等待客戶端發(fā)起請求服務端才能響應,延遲明顯更少;即使是和Comet等類似的長輪詢比較,其也能在短時間內更多次地傳遞數(shù)據(jù)。
- 保持連接狀態(tài)。與HTTP不同的是,Websocket需要先創(chuàng)建連接,這就使得其成為一種有狀態(tài)的協(xié)議,之后通