議實踐解析)
“Make MQ Great Again”這個口號出現(xiàn)在 COSCon‘25 與 Pulsar Developer Day 2025 的聯(lián)合會場上多少有些讓人會心一笑。作為一個從 ActiveMQ 時代寫消費端出身、后來又折騰過 Kafka 和 RocketMQ 的后端我對這個消息隊列的“文藝復興”主題既熟悉又好奇。消息中間件這個看似基礎、看似穩(wěn)定的領域在數(shù)據(jù)量爆炸、云原生普及、AI 應用大規(guī)模落地的當下正在經(jīng)歷一場并不喧嘩但非常硬核的重塑。這篇回顧寫的是我全程參加這場活動后的所見、所聞和所得既有會場里的高密度技術(shù)分享也有我在現(xiàn)場親手跑通的小實驗還有一些會后回來自己驗證過的經(jīng)驗。如果你想了解 Pulsar 為什么能在 2025 年重新把 MQ 這個老話題講出新內(nèi)容或者正在為團隊選型消息系統(tǒng)而糾結(jié)這篇內(nèi)容應該能給你一些參考。1. 開場印象MQ 不是“老古董”而是正在換發(fā)動機1.1 為什么“Make MQ Great Again”不是一句調(diào)侃活動公布主題時很多人在群里轉(zhuǎn)發(fā)“Make MQ Great Again”第一反應都是玩梗。但到了現(xiàn)場聽了幾場分享之后我意識到這句話其實很認真。消息隊列并不是一個需要“再次偉大”的過氣組件恰恰相反它在現(xiàn)代分布式系統(tǒng)里的位置比十年前更重要。過去我們聊 MQ主要是在聊削峰填谷、異步解耦、應用間通信現(xiàn)在聊 MQ大家關(guān)心的是實時數(shù)倉的接入層、AI Agent 的上下文傳遞、物聯(lián)網(wǎng)設備的海量事件接入、跨云跨地域的數(shù)據(jù)同步?;A能力沒變但承載的業(yè)務場景已經(jīng)換了一代。會場上有一張 PPT 我記得很清楚把現(xiàn)存主流消息系統(tǒng)的演進按時間軸排列傳統(tǒng)企業(yè)級 MQ、開源消息中間件、分布式日志系統(tǒng)、云原生消息平臺依次出現(xiàn)。Pulsar 屬于最后那一檔但它并不是簡單地“再做一款 Kafka”而是把底層存儲、計算、協(xié)議接入徹底拆開。這個架構(gòu)動機在多個演講里被反復強調(diào)讓一套引擎同時滿足隊列模型和流模型既保留消息確認、死信、順序消費這類 MQ 老用戶離不開的語義又提供流式系統(tǒng)需要的分區(qū)、重放、高吞吐和水平擴展?,F(xiàn)場有不少人問“Pulsar 是不是要取代 Kafka”幾乎每個講師都會先糾正這個問題。更準確的說法是Pulsar 想在 MQ 和流處理之間找到平衡點。Kafka 在流處理生態(tài)的地位短期內(nèi)難以撼動但很多企業(yè)的真實場景其實是混合型的一部分流量要求低延遲、強一致的消息投遞另一部分流量需要長時間保留、可回溯的流數(shù)據(jù)。傳統(tǒng)方案通常要同時維護兩套系統(tǒng)而 Pulsar 試圖用存儲和計算分離的架構(gòu)讓一套系統(tǒng)覆蓋兩種模式。這也是活動主題叫“Make MQ Great Again”的原因——不是在懷舊而是給 MQ 換一套新發(fā)動機。1.2 聯(lián)合場次的價值開源大會與開發(fā)者日擦出的火花這次是和 COSCon 合辦會場設置很有意思。COSCon 本身是綜合性開源大會觀眾里有很多做前端、AI、操作系統(tǒng)、開源的伙伴Pulsar Developer Day 則更垂直吸引的是消息系統(tǒng)和數(shù)據(jù)基礎設施的深度用戶。兩個群體放在一起產(chǎn)生了很奇妙的化學反應。一個做輔助駕駛系統(tǒng)的工程師和一個做量化交易平臺的架構(gòu)師竟然在同一個圓桌上聊 Pulsar 的背壓機制一個剛接觸消息隊列的大學生在動手實驗區(qū)用二十分鐘起了本地集群眼睛里全是光。這種組合讓 Pulsar 的開發(fā)者也意識到消息中間件的使用者正在變得更多元不再只是后端老炮。AI 應用需要把大模型調(diào)用記錄、工具調(diào)用事件、多輪會話上下文全部以事件流的方式存儲和分發(fā)IoT 平臺需要面向海量設備維持百萬級長連接同時還要把設備狀態(tài)變更可靠地同步到業(yè)務系統(tǒng)。這些新場景沒有那么多歷史包袱反而更愿意嘗試新架構(gòu)?;顒由虾脦讏鲅葜v的主題都集中在這些新用例上而不是單純講“我們比誰吞吐高”。聯(lián)合辦會的好處就在這里做開源的人能找到真實需求用開源的人能找到落地路徑。2. 關(guān)鍵技術(shù)分享拆解Pulsar 的“新三樣”2.1 存儲計算分離為什么是必答題而不是選答題Pulsar 最核心的設計就是 Broker 和 BookKeeper 分離。Broker 只負責協(xié)議解析、鑒權(quán)、路由和緩存真正持久化數(shù)據(jù)的是一組獨立的 BookKeeper 節(jié)點。這個架構(gòu)讓擴容變得非常優(yōu)雅需要提升讀寫吞吐就擴 Broker需要增加存儲容量或磁盤帶寬就擴 BookKeeper兩者完全獨立?,F(xiàn)場有講師把這種設計類比成“餐廳后廚和中央廚房分離”Broker 是前廳的傳菜口BookKeeper 是集中做菜的中央廚房高峰期可以直接加傳菜口的人手而不需要把整個后廚翻新一遍。對比之下傳統(tǒng)消息集群通常是“一體的”每個節(jié)點既處理請求又負責在本地磁盤上寫數(shù)據(jù)。集群擴到一定規(guī)模后某個節(jié)點磁盤滿了或 IO 被打滿處理能力就立刻形成瓶頸。存儲計算分離不是新概念但在消息領域把這個概念做成真正穩(wěn)定大規(guī)模落地的Pulsar 算是最徹底的一個。BookKeeper 的 Segment 存儲模型把數(shù)據(jù)切成小段分布在多個節(jié)點上配合 Quorum 機制保證多副本寫入。當一個 BookKeeper 節(jié)點故障時系統(tǒng)自動把該節(jié)點的 Segment 重新復制到其他節(jié)點整個過程對 Broker 和客戶端透明。我在現(xiàn)場最關(guān)心的其實是這個架構(gòu)在日常運維里的真實表現(xiàn)。有位分享嘉賓給了組數(shù)據(jù)他們在 100 多個 BookKeeper 節(jié)點上長期運行生產(chǎn)集群單日消息量超過萬億條。讓我印象更深的不是數(shù)字本身而是他提到“擴存儲節(jié)點就像加一塊普通硬盤一樣”不用遷移既有分區(qū)不用重新做數(shù)據(jù)均衡。這一點對運維團隊非常友好也是很多開源 MQ 在規(guī)?;笞钔吹狞c。2.2 多協(xié)議接入把“兼容”從口號變成可配置項Pulsar 原生支持多協(xié)議這件事以前只是在文檔里看到這次現(xiàn)場演示讓我徹底信服了。同一個 Pulsar 集群可以同時用 Kafka 協(xié)議客戶端、Pulsar 原生協(xié)議、MQTT 協(xié)議、AMQP 協(xié)議接入。演示的工程師現(xiàn)場開了一個 Kafka 的 console consumer 直接消費 Pulsar topic 里的消息又從 MQTT 客戶端發(fā)布了一條遙測數(shù)據(jù)兩邊的消息能在同一個 topic 上匯合。底下的觀眾先是安靜了一會兒隨后開始密集提問這個兼容是只做協(xié)議翻譯還是語義也完整映射答案比較令人安心Kafka 協(xié)議兼容層不是簡單地把字節(jié)流轉(zhuǎn)換一下而是盡量對齊了消費組、offset 提交、事務等核心語義。這意味著團隊里已有的 Kafka 客戶端、監(jiān)控工具、甚至部分 Flink Connector 都可以直接連到 Pulsar 上遷移成本被大幅壓縮。MQTT 的支持則帶了一堆額外的性能調(diào)優(yōu)參數(shù)比如 QoS 級別、保留消息、遺囑消息那些從 EMQX 之類的生態(tài)遷過來的用戶會覺得很親切。這種多協(xié)議策略有一個特別實際的價值公司內(nèi)部往往同時有好幾套消息系統(tǒng)因為不同部門各自選型形成了 Kafka、RabbitMQ、Pulsar 甚至老牌企業(yè)級 MQ 并存的局面。Pulsar 通過協(xié)議層粘合讓新老系統(tǒng)之間可以逐步遷移而非一次性推倒重來。現(xiàn)場有個比喻我很認同多協(xié)議不是讓你把所有雞蛋放進一個籃子而是給你一個可以慢慢搬家的中轉(zhuǎn)站。2.3 分層存儲與無狀態(tài) Broker成本視角下的殺手锏過去消息系統(tǒng)很難做到長期保存歷史數(shù)據(jù)要么存儲成本過高要么消費歷史消息會把集群壓垮。Pulsar 的分層存儲把熱數(shù)據(jù)放在 BookKeeper冷數(shù)據(jù)可以自動卸載到對象存儲比如 AWS S3、騰訊云 COS以及各類兼容 S3 的存儲。這個能力聽起來很輕松實際背后是兩個硬核設計一是 Broker 可以只緩存熱數(shù)據(jù)的索引和元數(shù)據(jù)二是數(shù)據(jù)卸載和回讀的流程完全自動化應用層不需要感知。現(xiàn)場展示了一個很“凡爾賽”的操作把一個 topic 的 retention 設置成“不刪除”然后生產(chǎn)了幾百萬條消息等數(shù)據(jù)自動從 BookKeeper 卸載到對象存儲后再用一個剛啟動的全新消費組從頭開始消費。消費過程中流量水位非常平?jīng)]有明顯的讀取毛刺。這套機制意味著我們可以真正把 MQ 當作一個“流式數(shù)據(jù)湖”的入口而不是用完即棄的臨時管道。也正是因為 Broker 無狀態(tài)Pulsar 在 Kubernetes 上跑得非常順。Pod 調(diào)度、滾動升級、故障自愈都不需要關(guān)心本地數(shù)據(jù)。現(xiàn)場動手實驗環(huán)節(jié)主辦方用的就是一套 Kind 集群一條命令部署了 Pulsar Operator然后通過 CRD 申請了一個三 BookKeeper、三 Broker 的集群。從提交 YAML 到集群 Ready 大概花了三四分鐘這個速度對開發(fā)者體驗來說相當重要。3. 動手實驗與實操記錄從零跑通一個 Pulsar 集群3.1 實驗環(huán)境準備Docker Compose 快速起飛在活動動手區(qū)主辦方準備了好幾臺實驗機器配置不算高8 核 16G 內(nèi)存。大多數(shù)人第一選擇是用 Docker Compose 快速起一個 standalone 集群。這條路徑對初學者最友好也是我建議第一次接觸 Pulsar 的朋友先嘗試的方式。下面是我在現(xiàn)場用到的啟動文件片段回來之后我在自己電腦上又驗證了一遍可以直接用。version: 3.8 services: pulsar: image: apachepulsar/pulsar:4.0.0 container_name: pulsar ports: - 6650:6650 - 8080:8080 environment: PULSAR_MEM: -Xms512m -Xmx512m -XX:MaxDirectMemorySize256m command: bin/pulsar standalone啟動只需要兩分鐘docker compose up -d docker exec -it pulsar bin/pulsar-admin clusters list看到standalone輸出就說明服務已經(jīng)起來了。這里要注意新版 Pulsar 的 standalone 模式和舊版細節(jié)差異比較大一些老文章中讓改standalone.conf的配置在這里不一定生效建議優(yōu)先查看官方文檔里對應版本的部分。啟動后可以立刻跑一個生產(chǎn)消費的連通性驗證docker exec -it pulsar bin/pulsar-client produce persist://public/default/test -m hello coscon -n 1 docker exec -it pulsar bin/pulsar-client consume persist://public/default/test -n 1 -p Earliest這個步驟順利的話你會看到一條消息從生產(chǎn)到消費的全過程?,F(xiàn)場很多第一次摸 Pulsar 的朋友在這一步就消除了陌生感原來消息隊列的體驗可以這么輕。之后再用pulsar-admin topics stats看 topic 的詳細統(tǒng)計就能直觀理解消息隊列的內(nèi)部狀態(tài)長什么樣。3.2 用 Pulsar Operator 在 Kind 里部署集群Docker Compose 適合體驗但如果你關(guān)注的是 K8s 環(huán)境下的真實運維那一定得試試 Pulsar Operator。在實驗區(qū)我們通過 Kind 創(chuàng)建了一個包含一個控制平面和三個工作節(jié)點的集群然后安裝證書管理器、Pulsar Operator再提交一個自定義資源。核心操作大致如下kind create cluster --name pulsar-demo --config - EOF kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 nodes: - role: control-plane - role: worker - role: worker - role: worker EOF部署 Operator 后創(chuàng)建一個PulsarCluster資源apiVersion: pulsar.apache.org/v1alpha1 kind: PulsarCluster metadata: name: demo-pulsar spec: broker: replicas: 3 image: apachepulsar/pulsar:4.0.0 bookkeeper: replicas: 3 image: apachepulsar/pulsar:4.0.0 volumes: - name: data emptyDir: {}等 Pod 都變成 Running 后把 Broker 服務端口轉(zhuǎn)發(fā)出來接上文同樣的pulsar-client命令就能訪問?,F(xiàn)場有人問為什么不用emptyDir來做生產(chǎn)環(huán)境答案顯然是演示環(huán)境不在乎數(shù)據(jù)持久化生產(chǎn)環(huán)境一定會用 PVC 掛獨立存儲卷。這里想提醒大家Operator 只是把繁瑣的部署邏輯封裝了但它不會替你決定存儲方案網(wǎng)絡策略資源配額這些依然要按生產(chǎn)標準來設計。3.3 性能驗證小規(guī)模也能看出架構(gòu)差異動手實驗區(qū)給我最大的驚喜不是“能跑”而是能自己動手做簡單的壓測驗證架構(gòu)行為。主辦方給每個小組發(fā)了腳本用 Pulsar 自帶的pulsar-perf工具進行生產(chǎn)壓測。我在 3 個 Broker 和 3 個 BookKeeper 的小集群上跑了一組對比先只擴 Broker 節(jié)點保持 BookKeeper 不變發(fā)現(xiàn)生產(chǎn)吞吐能明顯上漲然后只擴 BookKeeper 節(jié)點但擴大存儲吞吐能力和磁盤數(shù)量之后積壓消費的恢復速度更快了。命令本身很簡單docker exec -it pulsar bin/pulsar-perf produce -r 100000 -s 1024 -t persist://public/default/perf-topic現(xiàn)場跑出的吞吐是每秒鐘十幾萬條消息單條消息 1KB客戶端和集群都在同一臺機器上。這個數(shù)字不算夸張但它驗證了一個關(guān)鍵結(jié)論在存儲計算分離架構(gòu)下Broker 和存儲可以獨立調(diào)優(yōu)。對于做技術(shù)選型的人來說這種可拆分性意味著預算可以花在真正需要的地方。我還試著調(diào)低了 BookKeeper 的寫入副本數(shù)從默認的 3 降到 2生產(chǎn)延遲立刻下降但可用性也下降。這種親手體驗比看任何 benchmark 圖都更能幫助你理解“副本數(shù)不是越多越好而是要在一致性、延遲和成本之間做權(quán)衡”。4. 社區(qū)圓桌與開發(fā)者生態(tài)項目是代碼更是秩序4.1 從“用 Pulsar”到“改 Pulsar”的成長路徑圓桌環(huán)節(jié)請了幾位長期活躍的社區(qū)貢獻者其中一位分享了自己從用戶到提交者再到 PMC 成員的經(jīng)歷。他最早只是在公司里負責維護 Pulsar 集群遇到一個 訂閱模式相關(guān)的 bug提了個 issue后來被引導去修復一個較小的 broker 端并發(fā)問題。過程并不神秘先去讀pulsar-broker模塊的代碼跑相關(guān)測試然后提交 PR。從第一個 PR 到成為核心貢獻者他用了大約兩年。他提到一個很實用的建議新手貢獻者別一上來就選設計類的大 issue先從標注good first issue的入手比如完善監(jiān)控指標、修文檔、補測試用例。這類任務能讓你快速理解模塊邊界。Pulsar 社區(qū)里有一條不成文的規(guī)則一個補丁的價值不僅在于修復正確還在于你是否補充了清晰的測試和變更日志。社區(qū) Review discussions 會對代碼風格、異常處理、性能影響摳得很細但不會對新人苛刻到勸退。這個環(huán)節(jié)對我這樣的普通用戶也很有啟發(fā)。參與開源不只是為了刷簡歷而是當你真正理解了代碼邏輯之后你在排查生產(chǎn)故障時會有完全不同的直覺。我過去遇到 broker 內(nèi)存上漲第一反應是加內(nèi)存后來才學會從緩存配置、訂閱積壓、Backlog 大小這些角度去排查而這些認知正是通過讀社區(qū)代碼和討論學到的。4.2 用戶案例車聯(lián)網(wǎng)、量化交易與 AI Agent社區(qū)圓桌之后是幾個真實用戶案例的閃電分享。第一個案例來自智能汽車行業(yè)車端設備通過 MQTT 接入 Pulsar每天產(chǎn)生數(shù)億條車輛狀態(tài)事件包括電池SOC、定位、告警、OTA升級狀態(tài)。他們的需求很典型不同生命周期的事件有不同的優(yōu)先級車輛實時告警需要秒級投遞而歷史軌跡數(shù)據(jù)需要長期保留用于模型訓練。Pulsar 的多協(xié)議和分層存儲正好命中這兩個需求一套集群同時處理在線和離線鏈路。另一個案例讓我印象很深是一家量化交易團隊。他們的消息系統(tǒng)不僅要快還要在極端行情下不能丟消息。該團隊用 Pulsar 做訂單事件和行情數(shù)據(jù)的異步分發(fā)頻率不算高但每條消息都價值巨大。他們重點用到了 Pulsar 的事務消息能力和精確一次語義并定制了 Broker 的線程模型參數(shù)把端到端延遲控制在個位數(shù)毫秒級別。這個案例說明MQ 在某些場景下不是“盡力而為”的工具而是必須能提供強保證的分布式基礎設施。AI Agent 場景被多次提及很有意思。Agent 需要同時維護多個外部工具調(diào)用和多個會話上下文相當于一個復雜的異步并發(fā)系統(tǒng)。Pulsar 在這里被用作事件總線記錄 Agent 的每次決策、工具執(zhí)行結(jié)果和用戶反饋。這種數(shù)據(jù)天然是流式的需要支持回溯、重放和按時間線消費。相比傳統(tǒng)“應用日志 搜索存儲”的方案消息隊列給 AI 應用提供了一種更結(jié)構(gòu)化、更可靠的事件基礎設施??梢灶A見 2026 年會有更多 AI Infra 團隊把 Pulsar 納入技術(shù)棧。5. 常見問題與答疑實錄現(xiàn)場高頻問題整理5.1 消息積壓、重復消費與順序性現(xiàn)場答疑環(huán)節(jié)高頻問題仍然圍繞消息隊列“老三樣”積壓怎么辦、重復消息怎么處理、順序性怎么保證。有位朋友問“積壓幾百萬條消息能不能直接把分區(qū)數(shù)調(diào)大來加速消費”這個問題很典型。Pulsar 的分區(qū)擴容方式與 Kafka 相似擴容之后通過增加消費者并發(fā)確實能提升吞吐但積壓不只是消費端并發(fā)問題還要看下游系統(tǒng)能不能扛住壓力。我的建議一直是優(yōu)先確認 Backlog 是否已經(jīng)觸發(fā) Retention 策略避免數(shù)據(jù)被清理然后通過監(jiān)控看是消費者處理慢還是 Broker 分發(fā)有瓶頸。Pulsar 提供了比較完善的 Backlog 指標也可以用pulsar-admin topics stats查看每個訂閱的msgBacklog和blockedSubscriptionOnUnackedMessages。如果是因為下游處理能力不足盲目加消費者只會把下游壓垮。更穩(wěn)妥的方式是先擴容下游再逐步增加消費者實例并配合按累計積壓量自動伸縮的機制。重復消費這個問題Pulsar 可以從兩個層面回答消息確認語義支持最多一次、至少一次和精確一次事務消息能保證一批消息的原子性寫入但對下游來說仍然建議在消費者里做冪等設計。順序性則要按需取舍Pulsar 支持按 key 哈希到單個分區(qū)來保證同一 key 的消息順序但這會損失單個分區(qū)的寫入并行度。沒有任何消息系統(tǒng)能在“全局順序、無限并行、高性能”三個維度同時拉滿必須在建模階段想清楚需求邊界。5.2 集群運維元數(shù)據(jù)存儲、故障替換與版本升級很多人關(guān)心 Pulsar 依賴 ZooKeeper 或 etcd 做元數(shù)據(jù)存儲這件事。在 4.x 時代Pulsar 默認還會使用 ZooKeeper但社區(qū)正在推動用 etcd 作為替代減少外部依賴?,F(xiàn)場運維專家建議生產(chǎn)環(huán)境不要把元數(shù)據(jù)服務和其他業(yè)務混部并確保定期備份。雖然元數(shù)據(jù)量不大但一旦損壞整個集群的服務發(fā)現(xiàn)和主題元數(shù)據(jù)都會受影響。版本升級是另一個高頻問題。Pulsar 的版本迭代比較快跨大版本升級時要注意 broker 與 bookkeeper 之間的兼容性。社區(qū)給出的經(jīng)驗是升級前先閱讀 release notes尤其是配置項變更和移除項然后用金絲雀升級的方式先升級一個 broker 觀察穩(wěn)定再逐步推進。BookKeeper 的升級通常需要滾動重啟但 Pulsar 可以做到不停機前提是讀寫在升級過程中不能關(guān)。很多升級事故都出在順序上比如先升級了 ZooKeeper 又回到舊版這種來回橫跳很容易造成 meta 信息不兼容?,F(xiàn)場也有人問“能不能直接從一個 Kafka 集群平滑遷移到 Pulsar”。答案是可以做但過程需要規(guī)劃。比較推薦的路徑是先用 Pulsar 的 Kafka 協(xié)議兼容層讓新集群“偽裝”成 Kafka endpoint然后通過雙寫切換最后再裁剪舊集群。這套方案的核心收益是遷移過程中不需要修改客戶端代碼也不需要對生產(chǎn)流量做激進的割接。6. 一些會后想補充的個人經(jīng)驗活動結(jié)束后我又花了兩天時間在自己本地環(huán)境里復現(xiàn)了動手實驗中的主要操作順便測試了幾個現(xiàn)場來不及做的功能。這里想分享一個很小的經(jīng)驗很多人看到 Pulsar 的組件清單Broker、BookKeeper、ZooKeeper、Proxy會覺得很重但實際上跑一個開發(fā)測試環(huán)境遠比想象中輕。官方 Docker 鏡像里標準包已經(jīng)自動完成了配置組裝甚至連pulsar standalone這樣的命令都幫你把元數(shù)據(jù)服務一并拉起了。真正值得花時間研究的不是“怎么啟動”而是“生產(chǎn)環(huán)境里如何把每個組件的職責邊界劃清楚”。另一個體會是消息中間件這個領域其實特別需要“場景驅(qū)動”的學習方式。只看架構(gòu)圖、只對著文檔調(diào)參很難真正理解為什么存儲計算分離有意義。我建議你先從自己的業(yè)務出發(fā)找一個痛點比如“歷史消息無法回溯”“擴容總需要搬遷數(shù)據(jù)”“多個協(xié)議客戶端無法統(tǒng)一接入”然后帶著問題去 Pulsar 文檔里找答案。你會發(fā)現(xiàn)自己對消息系統(tǒng)的理解會從“會用一個工具”變成“能設計一套消息基礎設施”。最后再分享一件小事。圓桌結(jié)尾有觀眾問“Pulsar 社區(qū)未來一年最希望看到什么變化”一位維護者想了想說“希望更多新場景的人來‘折騰’我們而不是只要求我們變得更像老牌 MQ?!边@句話讓我挺觸動的。消息隊列從來不應該是保守的代名詞它值得在新架構(gòu)、新場景里被重新發(fā)明一遍。如果你也在關(guān)注 MQ 的演進希望這篇回顧能讓你感受到下一次技術(shù)選型時除了“用哪個老牌中間件”我們還可以有更多值得認真評估的選項。