CI持續集成:Gitlab&&Gerrit&&Jenkins部署集成


引言:

??隨著IT行業的不斷發展,軟件開發的復雜度也隨著不斷提高,軟件的開發團隊也越來越龐大,如何更好地協同整個團隊進行高效準確的工作,確保軟件開發的質量成為了開發過程中不可回避的問題。

??在軟件開發中,不同的功能模塊一般由不同的開發成員負責,同一功能模塊的各層代碼也可能是不同的開發成員編寫,經驗告訴我們,模塊之間的問題是最難解決的,也是最耗費時間的。它需要多個開發人員相互協作找出問題,而協作過程中的溝通所消耗的時間成本是相當高的。而且還可能因為溝通的不足導致模塊返工。

??事實上,在持續集成被提出來之前的傳統開發方法中常常出現這種情況:由不同程序員開發的單個小模塊可以單獨工作,但把它們集成為一個大的系統則可能失敗。而且集成失敗往往是把集成放在開發周期后期,甚至是在項目快結束前單列的一個“總裝階段”。眾所周知,問題發現的越晚,其修復的成本也就越高,耗時越長,而且經過新的修復工作后可能誕生新的錯誤,因此整個系統需要再次進行集成和測試,從而導致整個軟件的生產周期漫長且不可預知。

??為了解決由傳統開發方法帶來的弊端,人們開始采用“早集成、常集成”的持續集成策略。從最初的分階段集成,到后來的“每日構建” ,再發展到現在的持續集成(Continuous Integration,CI)。持續集成通過自動化構建、自動化測試以及自動化部署加上較高的集成頻率保證了開發系統中的問題能迅速被發現和修復,降低了集成失敗的風險,使得系統在開發中始終保持在一個穩定健康的集成狀態。

??持續集成服務器是自動構建系統中關鍵的一部分。Jenkins是一個開源項目,它提供了一種易于使用的持續集成系統,使開發者從繁雜的集成中解脫出來,專注于更為重要的業務邏輯實現上。同時 Jenkins 能實施監控集成中存在的錯誤,提供詳細的日志文件和提醒功能,還能用圖表的形式形象地展示項目構建的趨勢和穩定性。Jenkins還能通過自定義安裝插件來實現多種多樣的功能。持續集成服務器各系統實現功能如下:


1、Gitlab上進行代碼托管

??在Gitlab上創建開發組,加入開發人員,新建開發項目項目并設置權限為Private,普通用戶對該項目只有pull權限,不能直接進行push

??強制Review :在 Gitlab 上創建的項目,指定相關用戶只有Reporter權限,這樣用戶沒有權限使用git push功能,只能git review到Gerrit 系統上,Jenkins在監聽Gerrit上的項目事件會觸發構建任務來測試代碼, Jenkins 把測試結果通過 ssh gerrit 給這個項目打上 Verified (信息校驗)成功或失敗標記,成功通知其它人員 Review(代碼審核) 。

??Gitlab保護Master 分支:在 Gitlab 上創建的項目可以把 Master 分支保護起來,普通用戶可以自己創建分支并提交代碼到自己的分支上,沒有權限直接提交到Master分支,用戶最后提交申請把自己的分支 Merge 到 Master ,管理員收到 Merge 請求后, Review 后選擇是否合并。

??因為Gitlab和Gerrit做了同步,Gerrit上的代碼會同步到Gitlab上。

2、Gerrit審核代碼

??普通用戶將Gitlab里的項目clone到本地,修改代碼后,雖不能直接push到代碼中心 ,但是可以通過git review提交到Gerrit上進行審核。Gerrit相關審核員看到review信息后,判斷是否通過,通過即commit提交。然后,Gerrit代碼會和Gitlab完成同步。

??Gerrit的精髓在于不允許直接將本地修改同步到遠程倉庫。客戶機必須先push到遠程倉庫的refs/for/*分支上,等待審核。

??Gerrit上也可以對比代碼審核提交前后的內容狀態。

3、Jenkins代碼發布

??當用戶git review后,代碼通過Jenkins自動測試(verified)、人工review 后,代碼只是merge到了Gerrit的項目中,并沒有merge到 Gitlab的項目中,所以需要當 Gerrit 項目倉庫有變化時自動同步到Gitlab的項目倉庫中。Gerrit 自帶一個 Replication 功能,同時我們在安裝 Gerrit 時候默認安裝了這個 Plugin,通過添加replication.config 給 Gerrit即可。


CI持續集成系統安裝部署流程描述如下:

Gerrit部署配置

1、 安裝JDK

[root@Ubuntu]#sudo add-apt-repository ppa:webupd8team/java

[root@Ubuntu]#sudo apt-get update

[root@Ubuntu]#sudo apt-get install oracle-java8-installer

2、 安裝mysql

[root@Ubuntu]#sudo apt-get install mysql-server mysql-client #中途會讓你輸入一次root用戶密碼(密碼:root)

3、 創建gerrit數據庫

[root@Ubuntu]#mysql –uroot –p 進入mysql創建gerrit數據庫gerritdb

mysql>create database gerritdb CHARACTER SET utf8 COLLATE utf8_general_ci;

mysql>grant all on gerritdb.* to 'gerrit'@'localhost' identified by '123456';

mysql>flush privileges;

4、 安裝配置并啟動nginx(反向代理端口設為9095)

[root@Ubuntu]#sudo apt-get install nginx

[root@Ubuntu]#cd /etc/nginx/conf.d

[root@Ubuntu]#vim gerrit.conf
server {

 listen 9095;

 server_name localhost;

 allow all;

 deny all;

 auth_basic "Welcomme to Gerrit Code Review Site!";

 auth_basic_user_file /home/gerrit/gerrit_site/etc/passwords;

 location / {

 proxy_pass http://10.0.2.15:9091;

 }

 }
[root@Ubuntu]#sudo /etc/init.d/nginx start

5、 安裝git

[root@Ubuntu]#  sudo apt-get install git

6、 安裝git-review

[root@Ubuntu]#sudo apt-get install git-review

7、 安裝gerrit

[root@Ubuntu]#useradd –m gerrit

切換用戶gerrit

[root@Ubuntu]#su – gerrit

將gerrit安裝包gerrit-2.11.3.war放在相應目錄下,執行:

[gerrit@Ubuntu]$java -jar gerrit-2.11.3.war init -d ~/gerrit_site

安裝gerrit

安裝過程提示的配置項可在gerrit安裝完成后在gerrit配置文件中進行配置。

8、 配置gerrit

[gerrit@Ubuntu]$cd /home/gerrit/gerrit_site/etc

[gerrit@Ubuntu]$vi gerrit.config

配置文件內容:

[gerrit]

 basePath = git

 canonicalWebUrl = http://10.0.2.15:9091/

[database]

 type = mysql

 hostname = localhost

 database = gerritdb

 username = gerrit

[index]

 type = LUCENE

[auth]

 type = HTTP

[sendemail]

 smtpServer = smtp.qq.com

 smtpServerPort = 465

 smtpEncryption = ssl

 smtpUser = xxx@qq.com

 smtpPass = xxxxxxxxxxxx

 sslVerify = false

 from = CodeReview<xxx@qq.com>

[container]

 user = gerrit

 javaHome = /usr/lib/jvm/java-8-oracle/jre

[sshd]

 listenAddress = *:29418

[httpd]

 listenUrl = proxy-http://10.0.2.15:9091

[cache]

 directory = cache

9、 啟動gerrit

[gerrit@Ubuntu]$/home/gerrit/gerrit_site/bin/./gerrit.sh restart

10、 瀏覽器地址欄輸入http://10.0.2.15:9095訪問gerrit,彈出登錄對話框

瀏覽器訪問Gerrit

Gerrit搭建成功!

11、 gerrit添加用戶

注意:第一次加-c參數是為了創建密碼文件,默認第一個用戶是系統管理員

[root@Ubuntu]#  htpasswd -c /home/gerrit/gerrit_site/etc/passwords gerrit

New password:

Re-type new password:

[root@Ubuntu]#htpasswd /home/gerrit/gerrit_site/etc/password jenkins5062

New password:

Re-type new password:

[root@Ubuntu]#htpasswd /home/gerrit/gerrit_site/etc/password jenkins

New password:

Re-type new password:

12、 登錄gerrit并注冊用戶郵箱

1) 輸入用戶名密碼,進入gerrit頁面

輸入用戶名密碼,進入gerrit頁面

2) 打開My->Groups->Contact Information頁面進行郵箱注冊

用戶郵箱注冊

3)單擊Register New Email按鈕,在提示框內輸入郵箱地址,進行注冊

用戶郵箱注冊

3) 打開郵箱,查看驗證郵件,打開驗證鏈接,用戶郵箱注冊成功

用戶郵箱注冊成功

13、 生成用戶公私鑰并進行配置

1)切換到需要配置公私鑰的用戶,執行生成公私鑰操作

[gerrit@Ubuntu]$ su - gerrit

[gerrit@Ubuntu]$ ssh-keygen -t rsa -C gerrit5062@163.com         //產生公私鑰

 [gerrit@Ubuntu]$cat ~/.ssh/id_rsa.pub
獲取用戶公鑰

2)使用用戶賬號登錄gerrit系統,將公鑰添加到用戶的SSH Public keys

Gerrit添加用戶SSH Public keys

一、Gitlab部署配置

1、 安裝Gitlab

[root@Ubuntu] #sudo apt-get install -y curl openssh-server ca-certificates

[root@Ubuntu] #sudo apt-get install -y postfix

[root@Ubuntu]#curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ee/script.deb.sh | sudo bash

[root@Ubuntu] #sudo apt-get install gitlab-ee

[root@Ubuntu] #sudo gitlab-ctl reconfigure

2、 Gitlab配置

Gitlab配置信息位于/etc/gitlab/目錄下的gitlab.rb文件,

[root@Ubuntu] #cd /etc/gitlab/

[root@Ubuntu] #vim gitlab.rb配置gitlab,相關配置如下:
Gitlab配置文件信息
Gitlab配置文件信息
Gitlab配置文件信息
Gitlab配置文件信息

配置完成后,重新啟動gitlab

[root@Ubuntu] #sudo gitlab-ctl configure

3、 配置root用戶密碼,登錄gitlab

1)終端執行

  [root@Ubuntu] #gitlab-rails console production

irb(main):001:0>u=User.where(id:1).first

u.password = 'secret_pass'

 >u.password_confirmation = 'secret_pass'

>u.save!

2)root登錄gitlab

登錄gitlab
登錄gitlab

4) 添加用戶,此處新增gerrit用戶為管理員

新增gerrit用戶為管理員

5) gerrit用戶登錄gitlab,添加SSH Public Keys

Gitlab添加用戶gerrit SSH Public Keys

二、Jenkins部署配置

1、安裝jenkins

[root@Ubuntu] #wget -q -O - https://pkg.jenkins.io/debian/jenkins-ci.org.key | sudo apt-key add -

[root@Ubuntu] #sudo sh -c 'echo deb http://pkg.jenkins.io/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list'

[root@Ubuntu] #sudo apt-get update

[root@Ubuntu] #sudo apt-get install Jenkins

2、jenkins默認端口為8080,為防止端口沖突,重新配置端口號為8082

[root@Ubuntu] #cd /etc/default

[root@Ubuntu] #vim Jenkins
修改Jenkins配置文件

4、 啟動jenkins

[root@Ubuntu] #/etc/init.d/Jenkins start

5、 登錄jenkins

1) 初始默認密碼在/var/lib/Jenkins/secrets目錄下的initialAdminPassword文件中

cat /var/lib/Jenkins/secrets/initialAdminPassword

登錄后重新配置jenkins賬號密碼,默認管理員用戶為jenkins。

2) 登錄jenkins

Jenkins登陸頁面
Jenkins首頁

Jenkins搭建完成。

6、 jenkins系統配置

1) 進入Jenkins系統配置界面

Jenkins系統配置界面

Jenkins Location配置:

Jenkins Location配置

Email-Notification配置:

Email-Notification配置

2) 進入Jenkins插件管理界面

Jenkins插件管理

搜索選擇(Available)需要安裝的插件,(構建工具gradle,Gerrit事件觸發器gerrit_trigger, 版本控制工具Git plugin)

Available可安裝插件

構建工具(Gradle)實現項目的自動構建、自動測試、自動部署等功能。Gerrit事件觸發器Gerrit_trigger監聽Gerrit系統事件。版本控制工具(Git plugin)保證項目源碼處于有序的管理中,方便開發人員隨時獲取和提交變更。

三、Gitlab與Gerrit集成

1、Gitlab項目設置

管理員用戶在Gitlab系統新建開發組dev-group,新建項目user,將開發人員加入開發組并配置為reporter權限,reporter用戶沒有push權限,只能使用 git review 命令提交,而 git review 命令需要 .gitreview 文件存在于項目目錄里。管理員gerrit用戶添加.gitreview 文件

[root@Ubuntu] #su – gerrit

[gerrit@Ubuntu]$git clone [git@10.0.2.15:dev-group/user.git](mailto:git@10.0.2.15:dev-group/user.git)

[gerrit@Ubuntu]$cd user

[gerrit@Ubuntu]$ vim .gitreview
編輯.gitreview文件
編輯.gitreview文件

添加.gitreview到版本庫

[gerrit@Ubuntu]$ git add .gitreview

[gerrit@Ubuntu]$ git config --global user.name 'gerrit'

[gerrit@Ubuntu]$git config --global user.email 'gerrit5062@163.com'

[gerrit@Ubuntu]$ git commit .gitreview -m 'add .gitreview file by gerrit.'

[gerrit@Ubuntu]$ git push origin master

項目目錄下缺少.gitreview文件,開發人員git review時會報錯:

No '.gitreview' file found in this repository. We don't know where

your gerrit is. Please manually create a remote named "gerrit" and try

again.

2、Gerrit設置項目

gitlab上的項目能在gerrit上review的話,必須在gerrit上創建相同的項目,并有相同的倉庫文件,所以gerrit上的項目最好是從gitlab上git clone --bare過來,并且項目不要為空

1)clone --bare Gitlab上的倉庫到 Gerrit

[gerrit@Ubuntu]$ cd /home/gerrit/gerrit_site/git/       

[gerrit@Ubuntu]$ git clone --bare git@10.0.2.15:dev-group/user.git  

2)同步 Gerrit的user項目到 Gitlab 上的user項目目錄中

當用戶git review后,代碼通過 jenkins 測試、人工 review 后,代碼只是 merge 到了 Gerrit 的user項目中,并沒有 merge 到 Gitlab 的user項目中,所以需要當 Gerrit user項目倉庫有變化時自動同步到 Gitlab 的 user項目倉庫中。

Gerrit 自帶一個 Replication 功能,同時我們在安裝 Gerrit 時候默認安裝了這個 Plugin。添加一個 replication.config 給 Gerrit

[gerrit@Ubuntu]$ cd /home/gerrit/gerrit_site/etc/

[gerrit@Ubuntu]$vim replication.config

[remote "user"]

projects =user

url = git@10.0.2.15:dev-group/user.git

push = +refs/heads/*:refs/heads/*

push = +refs/tags/*:refs/tags/*

push = +refs/changes/*:refs/changes/*

threads = 3
添加replication.config配置文件
添加replication.config配置文件

設置gerrit用戶的 ~/.ssh/config

[gerrit@Ubuntu]$vim /home/gerrit/.ssh/config
 Host 10.0.2.15:

 IdentityFile ~/.ssh/id_rsa

 PreferredAuthentications publickey
添加配置用戶config文件

在gerrit用戶的~/.ssh/known_hosts 中,給10.0.2.15 添加 rsa 密鑰

[gerrit@Ubuntu]$sh -c "ssh-keyscan -t rsa 10.0.2.15>> /home/gerrit/.ssh/known_hosts"

[gerrit@Ubuntu]$sh -c "ssh-keygen -H -f /home/gerrit/.ssh/known_hosts"

重新啟動 Gerrit 服務 [gerrit@Ubuntu]$/home/gerrit/gerrit_site/bin/gerrit.sh restart

五、Gerrit與Jenkins集成

1、Gerrit配置時已經將jenkins配置為Gerrit用戶,將jenkins用戶的密鑰添加到Gerrit

 [root@Ubuntu] #su – Jenkins

[jenkins@Ubuntu]$cat .ssh/id_rsa.pub
獲取jenkins用戶的公鑰
獲取jenkins用戶的公鑰

2、Jenkins項目設置

1)Jenkins新建項目user并完成相關配置

Jenkins新建項目user
配置user項目信息

配置jenkins連接Gerrit倉庫

jenkins連接Gerrit倉庫

選擇監聽Gerrit event

監聽Gerrit event
監聽Gerrit event

選擇gradle構建項目

gradle構建
gradle構建

2、配置Gerrit_trigger plugin

1) Manage Jenkins->Gerrit Trigger進入配置界面

Gerrit Trigger配置

2)Add New Server

Add New Server

2) 填寫配置信息并測試,Test Conection success,配置成功

Test Conection success

3、配置Gradle插件

1)Manage Jenkins->Global Tool Configuration,完成Gradle配置

配置Gradle插件
配置Gradle插件

六、測試(操作手冊)

1、普通用戶jenkins5062 從Gitlab或Gerrit系統將項目clone到本地進行編輯,修改代碼后,不能直接push到代碼中心 ,可以通過git review提交到gerrit上進行審核。gerrit相關審核員看到review信息后,判斷是否通過,通過即Submit提交。

Gitlab代碼庫clone代碼到本地進行編輯

[jenkins5062@Ubuntu]$ git clone [git@10.0.2.15:dev-group/user.git](mailto:git@10.0.2.15:dev-group/user.git)
Gitlab代碼庫clone代碼到本地進行編輯

或者在Gerrit代碼庫clone代碼到本地進行編輯,用戶登錄Gerrit->Project->General, 選中clone with commit-msg hook,選擇SSH或HTTP,復制clone命令

Gitlab代碼庫clone代碼到本地進行編輯
Gitlab代碼庫clone代碼到本地進行編輯

2、項目編輯完成后提交審核

git add test

git commit –m “jenkins5062 change test”

git review
提交審核

如果開發者需要在Gerrit里保存一些需要較長時間完成的工作,可以使用

git review –D

命令進行提交,提交的代碼將被Gerrit標記為Draft狀態,Draft狀態下的change只有提交者自己和被開發者添加的reviewer及項目管理員可以看到。處于draft狀態的change一樣可以添加reviewer。

如果開發者git review后需要在當前版本下繼續修改,可在再次編輯文件后git commit時添加--amend參數,重新git review。

3、Gerrit進行代碼審核

1)用戶git review后,jenkins監聽Gerrit events,對提交的代碼進行構建

jenkins監聽Gerrit events,對提交的代碼進行構建
jenkins監聽Gerrit events,對提交的代碼進行構建

2)普通用戶登錄Gerrit進行審核,All->Open->Subject列表下列出提交的項目代碼,代碼已經過Jenkins自動測試(Verified +1)

普通用戶登錄Gerrit進行審核
普通用戶登錄Gerrit進行審核

Files->File Path->user/test查看代碼變更的詳細信息

查看代碼變更的詳細信息

3) 管理員登錄Gerrit系統審核All->Open->Subject列表

管理員登錄Gerrit系統審核
管理員登錄Gerrit系統審核
管理員登錄Gerrit系統審核

審核通過后Submit提交Gitlab并合并到主分支。當用戶git review后,代碼通過jenkins自動測試(verified)、人工review 后,代碼只是merge到了Gerrit的項目中,并沒有merge到 Gitlab的項目中,所以需要配置replication插件,當 Gerrit 項目倉庫有變化時自動同步到Gitlab的項目倉庫中。

管理員登錄Gerrit系統審核

系統發送郵件,提醒jenkins5062用戶代碼已Submit并合并到Gitlab代碼倉庫

系統發送郵件,提醒jenkins5062用戶代碼已Submit并合并到Gitlab代碼倉庫

如果審核不通過

Reply...標記-2 ->Post

審核不通過
審核不通過

jenkins5062收到郵件提醒,代碼未通過審核

jenkins5062收到郵件提醒,代碼未通過審核
jenkins5062收到郵件提醒,代碼未通過審核

4、登錄Gitlab查看項目更新

登錄Gitlab查看項目更新
登錄Gitlab查看項目更新

Gitlab代碼倉庫已完成代碼更新!

七、部署集成部分問題整理總結

1、找不到適配Ubuntu 32位版本的gitlab安裝源,重裝64位Ubuntu系統后,

gitlab正常安裝

2、gitlab安裝完成后,執行sudo gitlab-ctl reconfigure啟動命令,

報錯:


 Error executing action 'run' on resource 'bash[migrate

 gitlab-rails database]'

 LoadError:/opt/gitlab/embedded/lib/libre2.so.0: symbol _ZTVNSt7__

 cxx1119basic_sotringstreamIcSt11char_traitsIcESaIcEEE,version

 GLIBCXX_3.4.21 not defined in file libstdc++.so.6 with link time

 reference

原因:GCC版本太低,升級Ubuntu至 16.04LTS版本后完成部署

3、執行:ssh -p 29418 -i ~/.ssh/id_rsa 10.0.2.15 -l gerrit

報錯:

Unable to negotiate with 192.168.1.101 port 29418: no matching key exchange method found. Their offer: diffie-hellman-group1-sha1

解決:修改~/.ssh/config,加入

Host *

 KexAlgorithms +diffie-hellman-group1-sha1

4、添加jenkins用戶登錄gerrit時報

500 Internal Server Error
nginx/1.10.3 (Ubuntu)錯誤,

執行 chmod 777 passswords修改/home/gerrit/gerrit_site/etc/passwords的權限,修改文件權限后gerrit恢復正常訪問

5、用戶從gerrit上將代碼clone到本地時報錯

Unable to negotiate with 10.0.2.15 port 29418: no matching key exchange method found. Their offer: diffie-hellman-group1-sha1

在.ssh/config文件中添加語句:

Host *

 KexAlgorithms +diffie-hellman-group1-sha1

6、gerrit安裝報錯:

Exception in thread "main" com.google.gwtorm.server.OrmException: Cannot apply SQL

ALTER TABLE changes ADD submission_id VARCHAR(255) BINARY

修改數據庫設置,執行數據庫設置語句:

set global explicit_defaults_for_timestamp=1;

7、nginx 報403 Forbidden錯誤

反向代理nginx /etc/nginx/conf.d/gerrit.conf 中 auth_basic_user_file /home/gerrit/gerrit_site/passwords;

路徑錯誤,改為auth_basic_user_file /home/gerrit/gerrit_site/etc/passwords;

注意:IP配置問題,文件權限問題

8、gerrit用戶注冊郵箱發送驗證連接失敗

原因:

1). /etc/secure.config文件內沒有配置的發送郵箱密碼和gerrit.config中的密碼不一致

解決方法:配置/etc/secure.config smtpPass同gerrit.config中的smtpPass的配置保持一致。

2). 網易smtp.163.com服務器問題,DT:SPM 發送的郵件內容包含了未被許可的信息,或被系統識別為垃圾郵件。

請檢查是否有用戶發送病毒或者垃圾郵件;發件郵箱更換為qq郵箱

9、1.git review 提交代碼請求 可觸發jenkins自動測試,自動測試通過代碼被標記 Verified +1 后被提交gerrit進行審核,審核人員審核后通過后Review +2,Submit,修改后的代碼未同步到gitlab。

解決:Gerrit安裝配置replication 插件

10、jenkins build failure 構建錯誤,使用jenkins安裝的gradle插件進行項目構建。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,797評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,179評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,628評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,642評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,444評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,948評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,040評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,185評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,717評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,602評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,794評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,316評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,045評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,418評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,671評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,414評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,750評論 2 370