Supervisor的安裝和入門

前幾天準(zhǔn)備部署一個(gè)go應(yīng)用澡匪,由于目前go的daemon方案還不完善又活,只能借助其他工具進(jìn)行部署,所以發(fā)現(xiàn)了一個(gè)非常好用的進(jìn)程管理工具——Supervisor岔激。

Supervisor(http://supervisord.org/)是用Python實(shí)現(xiàn)的一款非常實(shí)用的進(jìn)程管理工具萎攒。supervisor會(huì)幫你把管理的應(yīng)用程序轉(zhuǎn)成daemon程序遇八,而且可以方便的通過(guò)命令開啟、關(guān)閉耍休、重啟等操作刃永,而且它管理的進(jìn)程一旦崩潰會(huì)自動(dòng)重啟,這樣就可以保證程序執(zhí)行中斷后的情況下有自我修復(fù)的功能羊精。

本文將介紹如何在CentOS上Supervisor的安裝和使用斯够。

1 安裝

1.1 安裝環(huán)境

可以先運(yùn)行以下命令看系統(tǒng)是否安裝了python,以及python的版本

[root@192 ~]# python -V

image

Supervisor需要的python版本是python2 2.4以上(暫未明確是否支持python3)

如果系統(tǒng)沒(méi)有安裝python2的話喧锦,可以使用系統(tǒng)自帶安裝工具安裝python2

[root@192 ~]# yum install python2

再安裝python包管理工具easy_install

[root@192 ~]# yum install python-setuptools

1.2 安裝supervisor

使用easy_install安裝supervisor

[root@192 ~]# easy_install supervisor

驗(yàn)證是否安裝成功

[root@192 ~]# supervisord -v

image

注意:supervisor的命令是supervisord读规,命令比名稱多一個(gè)d

supervisor主要是兩個(gè)命令:

  1. supervisord是主進(jìn)程命令,用于啟動(dòng)supervisor

  2. supervisorctl是管理命令裸违,用于管理supervisor中的應(yīng)用程序

2 配置

2.1 配置文件

執(zhí)行如下命令

[root@192 ~]# echo_supervisord_conf

我們可以看到一份標(biāo)準(zhǔn)的配置文件模板

下面簡(jiǎn)單說(shuō)明(翻譯)一下這份模板

[unix_http_server]
file=/tmp/supervisor.sock   ; UNIX socket文件默認(rèn)路徑,supervisorctl命令會(huì)使用到本昏。
;chmod=0700                 ; socket file mode (default 0700)
;chown=nobody:nogroup       ; socket file uid:gid owner
;username=user              ; default is no username (open server)
;password=123               ; default is no password (open server)

;[inet_http_server]         ; HTTP服務(wù)器供汛,提供Web UI管理界面。默認(rèn)不開啟涌穆。
;port=127.0.0.1:9001        ; Web管理后臺(tái)運(yùn)行的IP和端口怔昨,如果開放到公網(wǎng)上需注意安全性。
;username=user              ; Web管理后臺(tái)登錄的用戶名
;password=123               ; Web管理后臺(tái)登錄的密碼

[supervisord]
logfile=/tmp/supervisord.log ; 主進(jìn)程的日志文件路徑宿稀,默認(rèn)為當(dāng)前路徑下的supervisord.log即$CWD/supervisord.log
logfile_maxbytes=50MB        ; max main logfile bytes b4 rotation; default 50MB
logfile_backups=10           ; # of main logfile backups; 0 means none, default 10
loglevel=info                ; log level; default info; others: debug,warn,trace
pidfile=/tmp/supervisord.pid ; 主進(jìn)程編號(hào)文件趁舀,默認(rèn)文件名為supervisord.pid
nodaemon=false               ;主進(jìn)程是否在前臺(tái)啟動(dòng),默認(rèn)false即以守護(hù)進(jìn)程daemon的方式在后臺(tái)運(yùn)行祝沸。
minfds=1024                  ; 主進(jìn)程可以打開的文件描述符的最小數(shù)量矮烹,默認(rèn)為1024。
minprocs=200                 ; 主進(jìn)程可以打開的進(jìn)程最小數(shù)量罩锐,默認(rèn)為200奉狈。
;umask=022                   ; process file creation umask; default 022
;user=supervisord            ; setuid to this UNIX account at startup; recommended if root
;identifier=supervisor       ; supervisord identifier, default is 'supervisor'
;directory=/tmp              ; default is not to cd during start
;nocleanup=true              ; don't clean up tempfiles at start; default false
;childlogdir=/tmp            ; 'AUTO' child log dir, default $TEMP
;environment=KEY="value"     ; key value pairs to add to environment
;strip_ansi=false            ; strip ansi escape codes in logs; def. false

[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

[supervisorctl]      
serverurl=unix:///tmp/supervisor.sock ; 通過(guò)UNIX socket連接supervisord主進(jìn)程,路徑與unix_http_server部分的file一致涩惑。
;serverurl=http://127.0.0.1:9001 ; 使用HTTP方式連接supervisord主進(jìn)程
;username=chris              ; should be same as in [*_http_server] if set
;password=123                ; should be same as in [*_http_server] if set
;prompt=mysupervisor         ; cmd line prompt (default "supervisor")
;history_file=~/.sc_history  ; use readline history if available

;[program:theprogramname]     ; 被管理的進(jìn)程的配置參數(shù)仁期,theprogramname表示進(jìn)程的名字。
;command=/bin/cat              ; 程序啟動(dòng)命令的路徑
;process_name=%(program_name)s ; 用來(lái)表示supervisor進(jìn)程啟動(dòng)時(shí)的名字,是一個(gè)Python字符串表達(dá)式跛蛋,默認(rèn)為%(program_name)s熬的。
;numprocs=1                    ; 啟動(dòng)的進(jìn)程實(shí)例數(shù)
;directory=/tmp                ; 進(jìn)程運(yùn)行目錄
;umask=022                     ; umask for process (default None)
;priority=999                  ; 進(jìn)程啟動(dòng)優(yōu)先級(jí),默認(rèn)999赊级,值越小越優(yōu)先啟動(dòng)押框。控制程序啟動(dòng)和關(guān)閉的順序此衅,越早啟動(dòng)越晚關(guān)閉强戴。
;autostart=true                ; 在supervisord主進(jìn)程啟動(dòng)時(shí)此程序自動(dòng)啟動(dòng)
;startsecs=1                   ; 啟動(dòng)1秒后沒(méi)有異常退出則表示進(jìn)程正常運(yùn)行
;startretries=3                ; 啟動(dòng)失敗時(shí)自動(dòng)重試次數(shù),默認(rèn)為3次挡鞍。
;autorestart=unexpected        ;程序退出后自動(dòng)重啟骑歹,可選值為unexpected/true/false,unexpected表示進(jìn)程意外殺死后才重啟墨微。
;exitcodes=0                   ; 自動(dòng)重啟預(yù)設(shè)的退出返回碼道媚,默認(rèn)為0。
;stopsignal=QUIT               ; 當(dāng)收到stop請(qǐng)求時(shí)發(fā)送信號(hào)給程序翘县,默認(rèn)為TERM最域,可選值HUP/INT/QUIT/KILL/USR1/USR2
;stopwaitsecs=10               ; 操作系統(tǒng)給主進(jìn)程發(fā)送SIGCHILD信號(hào)時(shí)等待的時(shí)長(zhǎng)
;stopasgroup=false             ; send stop signal to the UNIX process group (default false)
;killasgroup=false             ; SIGKILL the UNIX process group (def false)
;user=chrism                   ; setuid to this UNIX account to run the program
;redirect_stderr=true          ; redirect proc stderr to stdout (default false)
;stdout_logfile=/a/path        ; stdout log path, NONE for none; default AUTO
;stdout_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)
;stdout_logfile_backups=10     ; # of stdout logfile backups (0 means none, default 10)
;stdout_capture_maxbytes=1MB   ; number of bytes in 'capturemode' (default 0)
;stdout_events_enabled=false   ; emit events on stdout writes (default false)
;stdout_syslog=false           ; send stdout to syslog with process name (default false)
;stderr_logfile=/a/path        ; stderr log path, NONE for none; default AUTO
;stderr_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)
;stderr_logfile_backups=10     ; # of stderr logfile backups (0 means none, default 10)
;stderr_capture_maxbytes=1MB   ; number of bytes in 'capturemode' (default 0)
;stderr_events_enabled=false   ; emit events on stderr writes (default false)
;stderr_syslog=false           ; send stderr to syslog with process name (default false)
;environment=A="1",B="2"       ; process environment additions (def no adds)
;serverurl=AUTO                ; override serverurl computation (childutils)

;[eventlistener:theeventlistenername]
;command=/bin/eventlistener    ; the program (relative uses PATH, can take args)
;process_name=%(program_name)s ; process_name expr (default %(program_name)s)
;numprocs=1                    ; number of processes copies to start (def 1)
;events=EVENT                  ; event notif. types to subscribe to (req'd)
;buffer_size=10                ; event buffer queue size (default 10)
;directory=/tmp                ; directory to cwd to before exec (def no cwd)
;umask=022                     ; umask for process (default None)
;priority=-1                   ; the relative start priority (default -1)
;autostart=true                ; start at supervisord start (default: true)
;startsecs=1                   ; # of secs prog must stay up to be running (def. 1)
;startretries=3                ; max # of serial start failures when starting (default 3)
;autorestart=unexpected        ; autorestart if exited after running (def: unexpected)
;exitcodes=0                   ; 'expected' exit codes used with autorestart (default 0)
;stopsignal=QUIT               ; signal used to kill process (default TERM)
;stopwaitsecs=10               ; max num secs to wait b4 SIGKILL (default 10)
;stopasgroup=false             ; send stop signal to the UNIX process group (default false)
;killasgroup=false             ; SIGKILL the UNIX process group (def false)
;user=chrism                   ; setuid to this UNIX account to run the program
;redirect_stderr=false         ; redirect_stderr=true is not allowed for eventlisteners
;stdout_logfile=/a/path        ; stdout log path, NONE for none; default AUTO
;stdout_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)
;stdout_logfile_backups=10     ; # of stdout logfile backups (0 means none, default 10)
;stdout_events_enabled=false   ; emit events on stdout writes (default false)
;stdout_syslog=false           ; send stdout to syslog with process name (default false)
;stderr_logfile=/a/path        ; stderr log path, NONE for none; default AUTO
;stderr_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)
;stderr_logfile_backups=10     ; # of stderr logfile backups (0 means none, default 10)
;stderr_events_enabled=false   ; emit events on stderr writes (default false)
;stderr_syslog=false           ; send stderr to syslog with process name (default false)
;environment=A="1",B="2"       ; process environment additions
;serverurl=AUTO                ; override serverurl computation (childutils)

;[group:thegroupname]          ; 組服務(wù)
;programs=progname1,progname2  ; 配置多個(gè)服務(wù)的名稱
;priority=999                  ; 啟動(dòng)優(yōu)先級(jí),默認(rèn)999锈麸。

;[include]                     镀脂; 包含配置文件
;files = relative/directory/*.ini

這個(gè)配置文件包含了supervisor主進(jìn)程配置和應(yīng)用程序(我們希望被管理的程序)配置,一般推薦將主程序配置和應(yīng)用程序配置分開配置忘伞。

2.1 配置

配置文件里面默認(rèn)將很多文件放置到/tmp/下薄翅,但是有時(shí)候系統(tǒng)會(huì)自動(dòng)清理該目錄的文件,導(dǎo)致supervisor無(wú)故掛掉或者控制不了氓奈,所以我們需要先創(chuàng)建幾個(gè)目錄來(lái)存放文件

首先翘魄,推薦創(chuàng)建/etc/supervisord.d/來(lái)放置應(yīng)用程序的配置

然后,推薦創(chuàng)建/var/supervisord/來(lái)放置sock和pid文件

最后舀奶,推薦創(chuàng)建/var/supervisord/log/來(lái)放置日志文件

下面的操作都是以這幾個(gè)路徑來(lái)配置

2.1.1 創(chuàng)建主進(jìn)程配置文件

生成主進(jìn)程配置文件

[root@192 ~]# echo_supervisord_conf > /etc/supervisord.conf

注意:主配置文件請(qǐng)以這個(gè)名稱放在這個(gè)目錄暑竟,如果放在其他地方請(qǐng)創(chuàng)建一個(gè)軟連接,否則supervisorctl將無(wú)法管理應(yīng)用程序

下面講一些需要修改的地方,不需要修改的保持原樣即可

[unix_http_server]
file=/var/supervisord/supervisor.sock   ; sock文件
..
..

;[inet_http_server]         ; 出于安全考慮這個(gè)模塊一般情況不開啟
..
..

[supervisord]
logfile=/var/supervisord/log/supervisord.log ; 主進(jìn)程log文件
..
..
pidfile=/var/supervisord/supervisord.pid ; pid文件
..
..
childlogdir=/var/supervisord/log            ; 應(yīng)用程序日志文件
..
..

[rpcinterface:supervisor]
..
..

[supervisorctl]
serverurl=unix:///var/supervisord/supervisor.sock ; 讀取主進(jìn)程sock文件
..
..

;[program:theprogramname]      ; 這個(gè)模塊是應(yīng)用程序配置育勺,在主進(jìn)程中可以刪除或者不管
..
..

;[eventlistener:theeventlistenername]  ;這個(gè)模塊在主進(jìn)程中可以刪除或者不管
..
..

;[group:thegroupname]
..
..

[include]                            ; 把這個(gè)模塊前面的';'去掉但荤,啟用這個(gè)模塊
files = /etc/supervisord.d/*.ini     ; 應(yīng)用程序配置目錄

2.1.2 創(chuàng)建應(yīng)用程序文件

首先,在/etc/supervisord.d/創(chuàng)建一個(gè)ini文件

[root@192 ~]# vim /etc/supervisord.d/demo.ini

然后把[program:theprogramname]模塊整個(gè)拷貝進(jìn)去

同樣涧至,講一些需要修改的地方

[program:demo_cat]             ; 名稱很重要纱兑,涉及后面的管理
command=/bin/cat              ; 應(yīng)用程序的路徑,以cat為例子
..
..
directory=/tmp               ; 應(yīng)用程序的運(yùn)行目錄化借。如果應(yīng)用程序涉及相對(duì)路徑的文件潜慎,這個(gè)一定要修改好
..
..
autostart=true                ; start at supervisord start (default: true)
startsecs=5                   ; 設(shè)置得太低可能會(huì)因?yàn)闆](méi)來(lái)得及啟動(dòng)被判啟動(dòng)失敗
startretries=3                ; max # of serial start failures when starting (default 3)
autorestart=true        ; when to restart if exited after running (def: unexpected)
..
..
stopasgroup=true             ; send stop signal to the UNIX process group (default false)
killasgroup=true             ; SIGKILL the UNIX process group (def false)
..
..
..

這樣就配置完成了

3 啟動(dòng)

3.1 啟動(dòng)supervisor

[root@192 ~]# supervisord -c /etc/supervisord.conf

使用該命令啟動(dòng)supervisor

查看是否啟動(dòng)成功

[root@192 ~]# supervisorctl status

image

可以看到,我們剛才配置的demo_cat程序已經(jīng)在運(yùn)行了

3.2 管理應(yīng)用程序

主要是通過(guò)supervisorctl來(lái)管理應(yīng)用程序

supervisorctl status                 // 查看所有應(yīng)用程序狀態(tài)
supervisorctl stop programxxx        // 停止某個(gè)應(yīng)用程序
supervisorctl start programxxx       // 啟動(dòng)某個(gè)應(yīng)用程序
supervisorctl restart programxxx     // 重啟某個(gè)應(yīng)用程序
supervisorctl stop all               // 停止所有應(yīng)用程序
supervisorctl reread                 // 讀取有更新(增加)的配置文件,不會(huì)啟動(dòng)新添加的程序
supervisorctl update                 // 更新配置文件變化并重啟變化的服務(wù)
supervisorctl reload                 // 更新配置并重啟supervisor
supervisorctl shutdown               // 停止supervisor
supervisorctl tail programxxx stdout // 查看某個(gè)應(yīng)用程序的輸出

同時(shí)铐炫,根據(jù)上面的配置垒手,supervisor會(huì)重定向應(yīng)用程序的輸出,并保存到/var/supervisord/log里面

image

3.3 supervisor開機(jī)自啟動(dòng)

新建開機(jī)啟動(dòng)服務(wù)

[root@192 ~]# vim /lib/systemd/system/supervisord.service

在supervisord.service中添加以下內(nèi)容:

# supervisord service for systemd (CentOS 7.0+)
# by ET-CS (https://github.com/ET-CS)
[Unit]
Description=Supervisor daemon
[Service]
Type=forking
ExecStart=/usr/bin/supervisord
ExecStop=/usr/bin/supervisorctl $OPTIONS shutdown
ExecReload=/usr/bin/supervisorctl $OPTIONS reload
KillMode=process
Restart=on-failure
RestartSec=42s
[Install]
WantedBy=multi-user.target

將服務(wù)腳本添加到systemctl自啟動(dòng)服務(wù):

[root@192 ~]# systemctl enable supervisord.service

重啟系統(tǒng)測(cè)試開機(jī)啟動(dòng)倒信。

4 可能遇到的問(wèn)題

4.1 error: <class 'socket.error'>, [Errno 113] No route to host: file: /usr/lib64/python2.7/socket.py line: 571

這個(gè)問(wèn)題網(wǎng)上很多人說(shuō)是防火墻問(wèn)題科贬,他們的解決辦法都不適用。supervisor是本地服務(wù)鳖悠,跟防火墻沒(méi)有關(guān)系榜掌。后面我發(fā)現(xiàn)是因?yàn)?code>supervisorctl默認(rèn)在/etc/里面有supervisord.conf。所以如果你的/etc/里面沒(méi)有supervisord.conf乘综,建議你建個(gè)軟連接憎账,把主程序配置文件連接過(guò)來(lái)。例如:

[root@192 ~]# ln -s /etc/supervisord.conf /etc/supervisord.conf

4.2 error: <class 'socket.error'>, [Errno 111] Connection refused: file: /usr/lib64/python2.7/socket.py line: 224

這個(gè)問(wèn)題是因?yàn)閟upervisor沒(méi)有啟動(dòng)導(dǎo)致的卡辰。請(qǐng)確認(rèn)superviosr是否已經(jīng)啟動(dòng)胞皱。

4.3 unix:///tmp/supervisor.sock no such file

這個(gè)問(wèn)題是因?yàn)閟ock文件不見了。sock文件被刪除一般是因?yàn)榉旁谀J(rèn)的/tmp/里面被系統(tǒng)刪除了九妈。也有可能跟我一樣反砌,根據(jù)網(wǎng)上其他supervisor開機(jī)自啟動(dòng)的辦法,將supervisrod.conf里面的nodaemon=false改成true萌朱,導(dǎo)致系統(tǒng)一直重啟supervisor宴树,sock文件也就會(huì)一直被刪除和創(chuàng)建。

5 更新

本人也是新手晶疼,歡迎大家一起討論學(xué)習(xí)酒贬。后面有新的學(xué)習(xí)經(jīng)驗(yàn)和體會(huì)會(huì)進(jìn)一步更新。


參考鏈接

  1. https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/12.3.md
  2. https://blog.csdn.net/xyang81/article/details/51555473
  3. https://www.missshi.cn/api/view/blog/5aafcf405b925d681e000000
  4. https://blog.csdn.net/u012724150/article/details/54616600
  5. http://www.reibang.com/p/3c70e12b656a
  6. https://blog.csdn.net/sinat_21302587/article/details/76836283
  7. http://wonse.info/centos7-supervisor-auto-start.html
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末冒晰,一起剝皮案震驚了整個(gè)濱河市同衣,隨后出現(xiàn)的幾起案子竟块,更是在濱河造成了極大的恐慌壶运,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,820評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件浪秘,死亡現(xiàn)場(chǎng)離奇詭異蒋情,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)耸携,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門棵癣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人夺衍,你說(shuō)我怎么就攤上這事狈谊。” “怎么了?”我有些...
    開封第一講書人閱讀 168,324評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵河劝,是天一觀的道長(zhǎng)壁榕。 經(jīng)常有香客問(wèn)我,道長(zhǎng)赎瞎,這世上最難降的妖魔是什么牌里? 我笑而不...
    開封第一講書人閱讀 59,714評(píng)論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮务甥,結(jié)果婚禮上牡辽,老公的妹妹穿的比我還像新娘。我一直安慰自己敞临,他們只是感情好态辛,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,724評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著哟绊,像睡著了一般因妙。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上票髓,一...
    開封第一講書人閱讀 52,328評(píng)論 1 310
  • 那天攀涵,我揣著相機(jī)與錄音,去河邊找鬼洽沟。 笑死以故,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的裆操。 我是一名探鬼主播怒详,決...
    沈念sama閱讀 40,897評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼踪区!你這毒婦竟也來(lái)了昆烁?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,804評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤缎岗,失蹤者是張志新(化名)和其女友劉穎静尼,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體传泊,經(jīng)...
    沈念sama閱讀 46,345評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡鼠渺,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,431評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了眷细。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片拦盹。...
    茶點(diǎn)故事閱讀 40,561評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖溪椎,靈堂內(nèi)的尸體忽然破棺而出普舆,到底是詐尸還是另有隱情恬口,我是刑警寧澤,帶...
    沈念sama閱讀 36,238評(píng)論 5 350
  • 正文 年R本政府宣布沼侣,位于F島的核電站楷兽,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏华临。R本人自食惡果不足惜芯杀,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,928評(píng)論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望雅潭。 院中可真熱鬧揭厚,春花似錦、人聲如沸扶供。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)椿浓。三九已至太援,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間扳碍,已是汗流浹背提岔。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留笋敞,地道東北人碱蒙。 一個(gè)月前我還...
    沈念sama閱讀 48,983評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像夯巷,于是被迫代替她去往敵國(guó)和親赛惩。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,573評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容