日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

RabbitMQ 高可用集群搭建及电商平台使用经验总结

發(fā)布時(shí)間:2023/12/20 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 RabbitMQ 高可用集群搭建及电商平台使用经验总结 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
  • 面向EDA(事件驅(qū)動(dòng)架構(gòu))的方式來設(shè)計(jì)你的消息

  • AMQP routing key的設(shè)計(jì)

  • RabbitMQ cluster搭建

  • Mirror queue policy設(shè)置

  • 兩個(gè)不錯(cuò)的RabbitMQ plugin 大型應(yīng)用插件(Sharding、Rederation)

  • Queue鏡像失敗手動(dòng)同步

  • 各集群配置同步方式(RabbitMQ export\import)

  • 客戶端連接方式(盡量采用AMQP組來動(dòng)態(tài)鏈接)

  • RabbitMQ 產(chǎn)線二次產(chǎn)品化封裝(消息補(bǔ)償、發(fā)送消息持久化、異常處理、監(jiān)控頁面、重復(fù)消息剔除)

  • 1.面向EDA(事件驅(qū)動(dòng)架構(gòu))的方式來設(shè)計(jì)你的消息

    在通常情況下你在使用消息中間件的時(shí)候,都是未經(jīng)設(shè)計(jì)的使用,你沒有把應(yīng)用架構(gòu)和系統(tǒng)架構(gòu)邊界搞清楚。消息中間件只是一個(gè)純粹的技術(shù)工具,當(dāng)你引入的時(shí)候是站在應(yīng)用架構(gòu)的角度引入的。這是架構(gòu)的角度,也是架構(gòu)的上帝視角,這樣你就不會(huì)用到最后發(fā)現(xiàn)越來越混亂,而且也無法結(jié)合軟件模式、方法論、最佳實(shí)踐來綜合提升系統(tǒng)的架構(gòu)能力。

    EDA(Event Driven Architecture,EDA) 事件驅(qū)動(dòng)架構(gòu),它是一種用來在SOA或者M(jìn)icro service中進(jìn)行的架構(gòu)模式。它的好處有幾個(gè),柔性具有很高的伸縮性。

    (具體參考本人的SOA架構(gòu)文章:SOA架構(gòu)設(shè)計(jì)經(jīng)驗(yàn)分享—架構(gòu)、職責(zé)、數(shù)據(jù)一致性)

    既然要EDA就要規(guī)劃好你當(dāng)前的系統(tǒng)邊界之內(nèi)有多少業(yè)務(wù)實(shí)體,這些實(shí)體是圍繞著領(lǐng)域模型而得來。所以這里不要很主觀的就定義一些你認(rèn)為的事件,這些事件要根據(jù)業(yè)務(wù)實(shí)體中的對(duì)象來設(shè)計(jì)。業(yè)務(wù)實(shí)體起碼是有唯一Identity的。比如,訂單、商品,圍繞著這些實(shí)體展開,訂單可能有幾個(gè)狀態(tài)是比較常用的,創(chuàng)建、支付、配送、取消。商品可能有價(jià)格、關(guān)鍵屬性修改等等。這些實(shí)體的抽象和提煉取決于你當(dāng)前的業(yè)務(wù)。

    (有關(guān)這方面內(nèi)容可以參考:《領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)》、《探索CQRS和事件源》)

    這些是相對(duì)理論的指導(dǎo)思想,有了這些之后你可以落地你的Rabbitmq,這樣你就不會(huì)跑偏了。比如,你的消息名稱不會(huì)是看起來沒結(jié)構(gòu)和層次的,deliveryMssage(配送消息)。而是應(yīng)該,order.delivery.ondeliveryEvented(訂單.配送.配送完成事件)這樣的結(jié)構(gòu)。

    當(dāng)你的層次結(jié)構(gòu)不滿足業(yè)務(wù)需求的時(shí)候,你可能還需要進(jìn)一步明確事件范圍,order.viporder.delivery.ondeliveryEvented(訂單.VIP訂單.配送.配送完成事件)。

    上圖是一個(gè)事件驅(qū)動(dòng)的基本場(chǎng)景,它最矚目的幾個(gè)特性就是這幾個(gè),首先是異步化的,可以大大提高系統(tǒng)的抗峰值能力。然后就是解耦,這不用說了,設(shè)計(jì)模式里的觀察者模式?jīng)]有人不知道它的好處。伸縮性,可以按需scaleout,比如rabbitmq的node可以很方便的加入。最終一致性解決了分布式系統(tǒng)的CAP定理的問題。

    2.AMQP routing key的設(shè)計(jì)

    AMQP協(xié)議中約定了routing key的設(shè)計(jì)和交互。為了實(shí)現(xiàn)訂閱發(fā)布功能,我們需要某種方式能夠訂閱自己所感興趣的事件。所以在AMQP中的Binding中,可以根據(jù)routing key來進(jìn)行模式匹配。所以,這里可以結(jié)合amqp routingkey與領(lǐng)域事件,發(fā)出來的事件就相當(dāng)于amqp中的routingkey,這樣可以完美的結(jié)合起來。

    你的事件肯定是隨著業(yè)務(wù)發(fā)展逐漸增加的,而這個(gè)事件集合也沒辦法在一開始就定義清楚,所以這里有一個(gè)需要注意的就是,綁定的時(shí)候千萬不要寫死具體的routing key。比如,order.delivery.OnDeliveryEvented,這是訂單配送,此時(shí)你Binding的時(shí)候routingkey就寫成了”order.delivery.OnDeliveryEvented”。未來訂單事件一擴(kuò)展,就會(huì)很麻煩,不相關(guān)的事件都被訂閱到,無法細(xì)化或者事件你無法獲取到,因?yàn)閞outingkey改變了。所以在綁定的時(shí)候記住具體點(diǎn)綁定,也就是借助字符串的模式匹配綁定,比如,*.delivery.*,*.onDeliveryEvented”這樣。將來越來越多的routingkey和event出來都不會(huì)影響你的綁定。你只需要根據(jù)自己的關(guān)心程度,綁定在事件的不同層級(jí)上即可。

    上圖中,orderBinding綁定了order事件,它訂閱了頂級(jí)事件,也就是說未來任何類型的訂單都可以被訂閱到,比如,order.normalorder.delivery.onDeliveryEvent也可以被訂閱到。而viporderBinding訂閱了viporder事件,如果發(fā)送了一個(gè)order.normalorder.delivery.onDeliveryEvent就跟它沒關(guān)系了。

    3.RabbitMQ cluster搭建

    搞清楚了應(yīng)用架構(gòu)的事情,我們開始著手搭建RabbitMQ cluster。rabbitmq這款A(yù)MQP產(chǎn)品是用erlang開發(fā)的,那么我們稍微介紹下erlang。

    我第一次正式接觸erlang就是從rabbitmq開始的,一開始并沒有太多感覺到特別的地方,后來才明白越明白越發(fā)現(xiàn)挺喜歡這門語言的。喜歡的理由就是,它是天然的分布式語言。這句話說起來好像挺平常的,但是當(dāng)你明白了.erlang.cookie機(jī)制之后才恍然大悟。瞬間頓悟了,為什么要用erlang來搞rabbitmq,而是它真的很適合信息交換之類的軟件。erlang是愛立信公司開發(fā)的專門用來開發(fā)高性能信息交換機(jī)的,想想也會(huì)覺得那些軟件的性能和穩(wěn)定性要求是極高的。RabbitMQ的節(jié)點(diǎn)發(fā)現(xiàn)和互連真的很方便,這在erlang的虛擬機(jī)中就集成了,而且具有高度容錯(cuò)能力。反正我對(duì)它很有好感。

    還有一點(diǎn)值得驕傲的是RabbitMQ是偉大的pivotal公司的,你應(yīng)該知道pivotal公司是干什么的,如果你還不清楚建議你立刻google下。

    一開始我并沒有太關(guān)注他們的copyright,后來對(duì)pivotal公司越來越佩服之后突然看到原來RabbitMQ也是他們家的,突然信心倍增。這就是影響力和口碑,看看人家公司的spring、springboot、spring cloud,佩服的五體投地。(RabbtiMQ 官網(wǎng):http://www.rabbitmq.com/)

    3.1.安裝erlang & RabbitMQ

    要想安裝RabbitMQ,首先需要安裝和配置好它的宿主環(huán)境erlang。去erlang官網(wǎng)下載好erlang otp_src源碼包,然后在本地執(zhí)行源碼安裝。(erlang官網(wǎng):http://www.erlang.org/)

    由于我本機(jī)已經(jīng)下載好了otp_src源碼包,我是使用的otp_src_19.1版本。下載好之后解壓縮,然后進(jìn)入目錄,執(zhí)行./configure --prefix=/usr/erlang/,進(jìn)行環(huán)境的檢查和安裝路徑的選擇。如果你提示“No curses library functions found”錯(cuò)誤,是因?yàn)槿鄙賑urses庫,yum install –y ncurses-devel。安裝后在進(jìn)行configure。

    如果沒有報(bào)錯(cuò)的話,就說明安裝成功了。你還需要配置下環(huán)境變量:

    export PATH=$PATH:/usr/erlang/bin

    source /etc/profile

    此時(shí)使用erl命令檢查下erlang是否能正常工作了。

    接下來安裝RabbitMQ,去官網(wǎng)下載運(yùn)行的包就行了。

    同樣要配置下環(huán)境變量,這樣你的命令才能被系統(tǒng)查找到。然后運(yùn)行rabbitmq實(shí)例。

    這里有一個(gè)需要注意,記得配置下hosts,在127.0.0.1里加上本機(jī)的名稱。erlang進(jìn)程需要host來進(jìn)行連接,所以它會(huì)檢查你的hosts配置。還需要設(shè)置下防火墻,三個(gè)端口要打開。15672是管理界面用的,25672是集群之間使用的端口,4369是erlang進(jìn)程epmd用來做node連接的。

    我配置了兩個(gè)節(jié)點(diǎn),192.168.0.105、192.168.0.107,現(xiàn)在已經(jīng)全部就緒。我們添加原始賬號(hào)進(jìn)入rabbitmq管理界面。

    3.2.配置RabbitMQ cluster

    先保證你的各個(gè)rabbitmq節(jié)點(diǎn)都是可以訪問的,且打開rabbitmq_management plugin,這樣可以當(dāng)出現(xiàn)某個(gè)節(jié)點(diǎn)掛掉之后可以切換到其他管理界面查看情況或者管理。

    打開管理界面插件:

    rabbitmq-plugins enable rabbitmq_management

    添加賬號(hào):

    rabbitmqctl add_user admin admin

    添加 權(quán)限tag

    rabbitmqctl set_user_tags admin administrator

    保證兩個(gè)節(jié)點(diǎn)都是可以正常工作的。下面我們就將這兩個(gè)節(jié)點(diǎn)連接起來形成高可用的cluster,這樣我們就可以讓我們的exchange、queue在這兩個(gè)節(jié)點(diǎn)之間復(fù)制,形成高可用的queue。

    cd 到你的home目錄下,我是在root下,里面有一個(gè)隱藏的.erlang.cookie文件,這就是我在前面介紹erlang時(shí)候提到的,這個(gè)文件是erlang用來發(fā)現(xiàn)和互連的基礎(chǔ)。我們需要做的很簡單,將兩個(gè)節(jié)點(diǎn)中的.erlang.cookie設(shè)置成一樣的。這是erlang的約定,一樣的cookie hash key他認(rèn)為是合法和正確的連接。

    .erlang.cookie默認(rèn)是只讀的,你需要修改下寫入權(quán)限,然后復(fù)制粘貼下cookie? 字符串即可。

    chmod u+w .erlang.cookie

    配置好了之后接下來配置hosts文件,erlang會(huì)使用hosts文件里的配置去發(fā)現(xiàn)節(jié)點(diǎn)。

    vim /etc/hosts

    192.168.0.107 rabbitmq_node2 ? ?
    192.168.0.105 rabbitmq_node1

    保證同樣的配置在所有的節(jié)點(diǎn)上都是相同的。驗(yàn)證你配置的正確不正確你只需要在你的機(jī)器上ping rabbitmq_node1,試下請(qǐng)求的ip是不是你配置的即可。按照DNS的請(qǐng)求原理,hosts是最高優(yōu)先權(quán),除非瀏覽器有緩存,你直接用ping就不會(huì)有問題的。

    選擇一個(gè)節(jié)點(diǎn)stop,然后連接到另外節(jié)點(diǎn)。

    rabbitmqctl stop_app

    rabbitmqctl join_cluster rabbit@rabbitmq_node2 ? ?

    Clustering node rabbit@rabbitmq_node1 with rabbit@rabbitmq_node2 ... ? ?

    rabbitmqctl start_app

    節(jié)點(diǎn)已經(jīng)連接成功。

    默認(rèn)情況下節(jié)點(diǎn)占用的memory是總內(nèi)存的40%,可以根據(jù)自己的用途仔細(xì)研究rabbitmq的配置項(xiàng)。為了提高性能,不需要兩個(gè)節(jié)點(diǎn)都是disc的節(jié)點(diǎn),所以我們需要啟動(dòng)一個(gè)節(jié)點(diǎn)為RAM模式。

    rabbitmqctl change_cluster_node_type? ram

    改變r(jià)abbitmq_node1為內(nèi)存節(jié)點(diǎn)模式。

    4.Mirror queue policy設(shè)置

    節(jié)點(diǎn)是準(zhǔn)備好了,接下來我們需要設(shè)置exchange、queue 高可用策略,這樣才能真的做到高可用。現(xiàn)在是物理上的機(jī)器或者說虛擬機(jī)節(jié)點(diǎn)是高可用的,但是里面的對(duì)象需要我們進(jìn)行配置策略。

    RabbitMQ支持很好的策略模式,需要管理員才能操作。

    首先我們需要?jiǎng)?chuàng)建一個(gè)屬于自己業(yè)務(wù)范圍內(nèi)的vhost,標(biāo)示一個(gè)邏輯上的獨(dú)立空間,所有的賬號(hào)、策略、隊(duì)列都是強(qiáng)制在某個(gè)虛擬機(jī)里的。我創(chuàng)建了一個(gè)common vhost。

    開始添加policie。

    最主要是Apply to ,可以作用在exchange或者queues上,當(dāng)然也可以包含這兩個(gè)。策略選擇還是比較豐富的,最常用的是HAmode,還有MessageTTL(消息的過期時(shí)間)。這些策略按照幾個(gè)維度分組了,有跟高可用相關(guān)的,有Federation(集群之間同步消息)相關(guān)的 ,有Queue相關(guān)的,還有Exchange相關(guān)的。可以根據(jù)的業(yè)務(wù)場(chǎng)景進(jìn)行調(diào)整。

    我們定義了策略的匹配模式.order.,這樣可以避免將所有的exchange、queue都鏡像了。

    我們新建了一個(gè)ex.order.topic exchange,它的features中應(yīng)用了exchange_queue_ha策略。(相同的策略是無法疊加使用的。)其他的exchange并沒有應(yīng)用這個(gè)策略,是因?yàn)槲覀兊膒attern限定了只匹配.order.的名稱。

    創(chuàng)建一個(gè)qu.order.crm queue,注意看它的node屬性里有一個(gè)”Synchronised mirrors:rabbit@rabbitmq_node2“鏡像復(fù)制。features里也應(yīng)用了exchange_queue_ha策略。這個(gè)時(shí)候,隊(duì)列其實(shí)在兩個(gè)節(jié)點(diǎn)里都是有的,雖然我們創(chuàng)建的時(shí)候是在rabbit@rabbitmq_node1里的,但是它會(huì)復(fù)制到集群里的其他節(jié)點(diǎn)。在創(chuàng)建HAmode的時(shí)候可以提供HA params參數(shù),來限定復(fù)制節(jié)點(diǎn)的個(gè)數(shù),這通常用來提高性能和HA之間的平衡。

    5.兩個(gè)不錯(cuò)的RabbitMQ plugin 大型應(yīng)用插件(Sharding、Rederation)

    在rabbitmq-plugins中有兩個(gè)plugin還是可以試著研究研究的。rabbitmq-plugins list。

    rabbitmq-plugins list ? ?
    Configured: E = explicitly enabled; e = implicitly enabled ? ?
    | Status:?? * = running on rabbit@rabbitmq_node1 ? ?
    |/ ? ?
    [e*] amqp_client?????????????????????? 3.6.5 ? ?
    [? ] cowboy??????????????????????????? 1.0.3 ? ?
    [? ] cowlib??????????????????????????? 1.0.1 ? ?
    [e*] mochiweb????????????????????????? 2.13.1 ? ?
    [? ] rabbitmq_amqp1_0????????????????? 3.6.5 ? ?
    [? ] rabbitmq_auth_backend_ldap??????? 3.6.5 ? ?
    [? ] rabbitmq_auth_mechanism_ssl?????? 3.6.5 ? ?
    [? ] rabbitmq_consistent_hash_exchange 3.6.5 ? ?
    [? ] rabbitmq_event_exchange?????????? 3.6.5 ? ?
    [? ] rabbitmq_federation?????????????? 3.6.5 ? ?
    [? ] rabbitmq_federation_management??? 3.6.5 ? ?
    [? ] rabbitmq_jms_topic_exchange?????? 3.6.5 ? ?
    [E*] rabbitmq_management?????????????? 3.6.5 ? ?
    [e*] rabbitmq_management_agent???????? 3.6.5 ? ?
    [? ] rabbitmq_management_visualiser??? 3.6.5 ? ?
    [? ] rabbitmq_mqtt???????????????????? 3.6.5 ? ?
    [? ] rabbitmq_recent_history_exchange? 1.2.1 ? ?
    [? ] rabbitmq_sharding???????????????? 0.1.0 ? ?
    [? ] rabbitmq_shovel?????????????????? 3.6.5 ? ?
    [? ] rabbitmq_shovel_management??????? 3.6.5 ? ?
    [? ] rabbitmq_stomp??????????????????? 3.6.5 ? ?
    [? ] rabbitmq_top????????????????????? 3.6.5 ? ?
    [? ] rabbitmq_tracing????????????????? 3.6.5 ? ?
    [? ] rabbitmq_trust_store????????????? 3.6.5 ? ?
    [e*] rabbitmq_web_dispatch???????????? 3.6.5 ? ?
    [? ] rabbitmq_web_stomp??????????????? 3.6.5 ? ?
    [? ] rabbitmq_web_stomp_examples?????? 3.6.5 ? ?
    [? ] sockjs??????????????????????????? 0.3.4 ? ?
    [e*] webmachine??????????????????????? 1.10.3

    rabbitmq_sharding、rabbitmq_federation,rabbitmq_sharding的版本有點(diǎn)低了,github地址:https://github.com/rabbitmq/rabbitmq-sharding

    Rederation 可以用來進(jìn)行跨cluster或者node之間同步消息。http://www.rabbitmq.com/federated-exchanges.html

    這個(gè)用來在不同的domain之間傳遞消息還是個(gè)不錯(cuò)的解決方案,跨機(jī)房或者跨網(wǎng)絡(luò)區(qū)域,訂閱別人的rabbitmq消息始終不太穩(wěn)定,可以用這種方式來傳遞消息。

    6.Queue鏡像失敗手動(dòng)同步

    有時(shí)候可能由于各種原因?qū)е聁ueue mirror失敗,這個(gè)時(shí)候可以手動(dòng)進(jìn)行同步,而不是像其他分布式系統(tǒng)來重啟節(jié)點(diǎn)或者重建數(shù)據(jù)。

    這個(gè)還是比較方便的,有時(shí)候總有那么幾個(gè)小問題需要你手動(dòng)處理的。

    7.各集群配置同步方式(RabbitMQ export\import)

    各個(gè)環(huán)境的集群配置同步也是個(gè)日常運(yùn)維的問題,還好RabbitMQ也提供了相關(guān)工具。

    8.客戶端連接方式(盡量采用AMQP組來動(dòng)態(tài)鏈接)

    由于RabbitMQ是AMQP協(xié)議的實(shí)現(xiàn),所以在進(jìn)行遠(yuǎn)程連接的時(shí)候盡量采用amqp協(xié)議的方式連接。

    var amqpList = new List<AmqpTcpEndpoint> ? ?
    { ? ?
    ??? new AmqpTcpEndpoint(new Uri("amqp://192.168.0.105:5672")), ? ?
    ??? new AmqpTcpEndpoint(new Uri("amqp://192.168.0.107:5672")) ? ?
    }; ? ?

    關(guān)于集群的vip方案其實(shí)也是需要綜合考慮的,如果是統(tǒng)一的地址會(huì)面臨三個(gè)問題,DNS、LoadBalance、VIP,這三個(gè)點(diǎn)都有可能導(dǎo)致集群連接不上。現(xiàn)在越來越多的方案傾向于在客戶端做負(fù)載和故障轉(zhuǎn)移,這有很多好處,消除了中間節(jié)點(diǎn)帶來的故障概率。如果這三個(gè)點(diǎn)加在一起出現(xiàn)的可用性指標(biāo)肯定是比直接在客戶端連接的低的多。

    我們碰到最多就是VIP的問題,這類系統(tǒng)的VIP不同于數(shù)據(jù)庫,數(shù)據(jù)庫的master\slave大多都是要人工check后才切換,不會(huì)隨便自動(dòng)的切換主從庫。而非數(shù)據(jù)庫的VIP大多都是Keepalived自動(dòng)檢測(cè)切換,這帶來一些列問題,包括連接重試、心跳保持。這只是VIP的出錯(cuò)場(chǎng)景之一。還有LoadBalance帶來的問題,DNS出錯(cuò)的可能性也是很大。所以我傾向于使用客戶端來做這些。

    有幾個(gè)地方很重要,第一個(gè)就是消息的Persistent持久化狀態(tài)要帶上,第二個(gè)就是ContentType,這個(gè)屬性很實(shí)用,方便你查看消息的正文。

    如果沒設(shè)置,默認(rèn)是null。

    第三個(gè)就是AutomaticRecoveryEnabled,自動(dòng)連接重試,這致命重要。當(dāng)上面的VIP切換之后這個(gè)可以保命。第四個(gè)就是TopologyRecoveryEnabled,重新恢復(fù)Exchange、queue、binding。在出現(xiàn)網(wǎng)絡(luò)斷開之后,一旦恢復(fù)連接就會(huì)恢復(fù)這些設(shè)置以保證是最新的設(shè)置。

    9.RabbitMQ 產(chǎn)線二次產(chǎn)品化封裝(消息補(bǔ)償、發(fā)送消息持久化、異常處理、監(jiān)控頁面、重復(fù)消息剔除)

    不管rabbitmq保證的多么強(qiáng)壯,多么高可用,記住一定要有備用方案。

    在之前我寫了一篇文章,WebAPi的可視化輸出模式(RabbitMQ、消息補(bǔ)償相關(guān))——所有webapi似乎都缺失的一個(gè)功能

    說了就是消息的持久化和補(bǔ)償。

    一旦將發(fā)送和接受的消息持久化之后我們能做到事情就比較多了。消息補(bǔ)償是可以做的,異常也不用擔(dān)心。但是在發(fā)送消息的時(shí)候一定要注意,是先持久化消息在業(yè)務(wù)邏輯處理。為了應(yīng)對(duì)特殊活動(dòng)的監(jiān)控,還可以開發(fā)一定的業(yè)務(wù)來監(jiān)控消息的接受和處理的數(shù)量,然后自動(dòng)補(bǔ)償。

    在開發(fā)補(bǔ)償程序的時(shí)候有一個(gè)邏輯挺饒人的,當(dāng)你對(duì)某一個(gè)消息進(jìn)行補(bǔ)償?shù)臅r(shí)候會(huì)多出發(fā)送消息,而接受的消息肯定是比你發(fā)送的少。所以你在統(tǒng)計(jì)的時(shí)候記得DISTINCT下。

    總結(jié)

    以上是生活随笔為你收集整理的RabbitMQ 高可用集群搭建及电商平台使用经验总结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。