前端工程化:保姆級(jí)教學(xué) Jenkins 部署前端項(xiàng)目

DevOps

提到 Jenkins嘶炭,想到的第一個(gè)概念就是 CI/CD 在這之前應(yīng)該再了解一個(gè)概念赂鲤。

DevOps DevelopmentOperations 的組合,是一種方法論肠阱,并不特指某種技術(shù)或者工具师溅。DevOps 是一種重視 Dev 開發(fā)人員和 Ops 運(yùn)維人員之間溝通、協(xié)作的流程似踱。通過自動(dòng)化的軟件交付隅熙,使軟件的構(gòu)建,測(cè)試核芽,發(fā)布更加的快捷猛们、穩(wěn)定、可靠狞洋。

CI

CI 的英文名稱是Continuous Integration弯淘,中文翻譯為:持續(xù)集成。

試想軟件在開發(fā)過程中吉懊,需要不斷的提交庐橙,合并進(jìn)行單元測(cè)試和發(fā)布測(cè)試版本等等,這一過程是痛苦的借嗽。持續(xù)集成CI是在源代碼變更后自動(dòng)檢測(cè)态鳖、拉取、構(gòu)建的過程恶导。

CD

CD 對(duì)應(yīng)兩個(gè)概念 持續(xù)交付Continuous Delivery 持續(xù)部署Continuous Deployment

持續(xù)交付

提交交付顧名思義是要拿出點(diǎn)東西的浆竭。在 CI 的自動(dòng)化流程階段后,運(yùn)維團(tuán)隊(duì)可以快速、輕松地將應(yīng)用部署到生產(chǎn)環(huán)境中或發(fā)布給最終使用的用戶邦泄。

從前端的角度考慮删窒,在某些情況下肯定是不能直接通過自動(dòng)化的方式將最終的 build 結(jié)果直接扔到生產(chǎn)機(jī)的。持續(xù)交互就是可持續(xù)性交付供生產(chǎn)使用的的最終 build顺囊。最后通過運(yùn)維或者后端小伙伴進(jìn)行部署肌索。

持續(xù)部署

作為持續(xù)交付的延伸,持續(xù)部署可以自動(dòng)將應(yīng)用發(fā)布到生產(chǎn)環(huán)境特碳。

Jenkins 安裝

示例服務(wù)器為 阿里云 CentOS 服務(wù)器诚亚。安全組中增加 8080 端口 Jenkins 默認(rèn)占用

Jenkins 安裝大體分兩種方式,一種使用 Docker 另一種則是直接安裝午乓,示例選擇后者站宗。不管使用哪種方式安裝,最終使用層面都是一樣的益愈。 Linux 安裝梢灭, Docker 安裝

<details><summary>點(diǎn)擊查看Linux安裝過程</summary>

# 下載 Jenkins 資源
sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat/jenkins.repo
# 獲取并導(dǎo)入信任 的包制作者的秘鑰
sudo rpm --import https://pkg.jenkins.io/redhat/jenkins.io.key
# 升級(jí) yum 源中的所有包
sudo yum upgrade
# Jenkins 依賴于 java 所以需要安裝 JDK
sudo yum install java-11-openjdk
# 安裝 Jenkins
sudo yum install jenkins
復(fù)制代碼

如果最終 Jenkins 沒有找到包而導(dǎo)致沒有安裝成功,檢查第一步和第二部執(zhí)行結(jié)果并重新執(zhí)行腕唧。

可以使用 systemctl 命令管理 Jenkins 服務(wù) systemctl

# 啟動(dòng) Jenkins 服務(wù)
systemctl start jenkins
# 重啟 Jenkins 服務(wù)
systemctl restart jenkins
# 停止 Jenkins 服務(wù)
systemctl stop jenkins
# 查看 Jenkins 服務(wù)狀態(tài)
systemctl status jenkins
復(fù)制代碼

啟動(dòng)服務(wù)后訪問服務(wù)器地址 + 8080 端口或辖,Jenkins 默認(rèn)為 8080 端口瘾英。</details>

Jenkins 使用及 Freestyle 任務(wù)構(gòu)建

首次進(jìn)入使用 cat /var/lib/jenkins/secrets/initialAdminPassword 查看密碼枣接。

隨后進(jìn)入插件安裝頁面,暫時(shí)安裝系統(tǒng)推薦插件即可缺谴。

然后創(chuàng)建用戶

構(gòu)建目標(biāo):拉取 github 代碼

點(diǎn)擊 新建 Item 創(chuàng)建一個(gè) Freestyle Project

源碼管理 處選擇 git 但惶,輸入倉庫地址,點(diǎn)擊添加湿蛔。

輸入 github 賬號(hào)和密碼膀曾,這里的密碼有時(shí)候可能會(huì)出現(xiàn)問題,可以使用 token github 如何生成 token 阳啥?

配置只是一方面添谊,同時(shí)服務(wù)器也要具備 git 環(huán)境。 yum install git

構(gòu)建目標(biāo):部署到本機(jī)

部署前端項(xiàng)目肯定是離不開 nginx 的察迟。 yum install nginx斩狱。

安裝完成后同樣可以使用 systemctl 命令管理 nginx 服務(wù)。

nginx 具體配置這里就不說了扎瓶。本示例項(xiàng)目中所踊,靜態(tài)文件托管目錄為 /usr/share/nginx/html/dist

接著來到 Jenkins 這里概荷。想要部署前端項(xiàng)目還需要依賴一個(gè) Node 環(huán)境秕岛,需要在 Manage Jenkins -> Manage Plugins 在可選插件中搜索 nodejs 選擇對(duì)應(yīng)插件進(jìn)行安裝,安裝完成后需要重啟才會(huì)生效。

然后到 系統(tǒng)管理 -> 全局工具配置 中配置 Node (吐槽:沒有安裝任何插件時(shí)系統(tǒng)管理以及其子頁面全是英文继薛,安裝完插件后又變成了中文修壕。這國際化不知道是系統(tǒng)原因還是它的原因 ??)。

隨后去修改剛才創(chuàng)建的任務(wù)惋增。在 構(gòu)建環(huán)境 中會(huì)多出一個(gè)選項(xiàng) Provide Node & npm bin/ folder to PATH 勾選即可叠殷。然后在 構(gòu)建 中選擇 增加構(gòu)建步驟 -> 執(zhí)行 shell 輸入打包發(fā)布相關(guān)的命令。Jenkins 會(huì)逐行執(zhí)行诈皿。

npm install yarn -g
yarn install
yarn build
# 打包 build 后的文件
tar -zcvf dist.tar.gz dist/
# 刪除 build 后的文件
rm -rf dist/
# 移動(dòng) build 后的壓縮包到 nginx 托管目錄下林束。
sudo mv dist.tar.gz /usr/share/nginx/html
# 進(jìn)入托管目錄下
cd /usr/share/nginx/html
# 解壓
sudo tar -zxcf dist.tar.gz
# 刪除壓縮包
sudo rm -rf dist.tar.gz
復(fù)制代碼
  • 由于項(xiàng)目構(gòu)建時(shí)是在 Jenkins 的工作目錄下執(zhí)行腳本,會(huì)出現(xiàn)權(quán)限問題稽亏。導(dǎo)致即使使用了 sudo 還會(huì)出現(xiàn)類似以下錯(cuò)誤壶冒。
We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:

    #1) Respect the privacy of others.
    #2) Think before you type.
    #3) With great power comes great responsibility.
復(fù)制代碼

解決方案:在 /etc/sudoers 文件中增加 jenkins ALL=(ALL) NOPASSWD:ALL 表示在執(zhí)行 sudo 時(shí)不需要輸入密碼。

  • 如果不使用 sudo 則會(huì)出現(xiàn)以下錯(cuò)誤截歉。
xxxxxxx: Permission denied
復(fù)制代碼

解決方案:修改 /lib/systemed/system/jenkins.service 文件胖腾。將 User=jenkins 修改為 User=root,表示給 Jenkins 賦權(quán)限瘪松。修改配置文件后記得重啟服務(wù)咸作。

  • 構(gòu)建的過程中還可能出現(xiàn)以下錯(cuò)誤
ERROR: Error fetching remote repo 'origin'
復(fù)制代碼

解決方案:由于需要構(gòu)建的代碼在 github 上面,這種錯(cuò)誤表示拉取代碼失敗了宵睦,重試幾次就可以了记罚。

工作目錄

上面提到一個(gè)很重要的概念就是 工作目錄 在上面的 shell 默認(rèn)就是在這里執(zhí)行的。工作目錄是由兩部分組成壳嚎。

  • /var/lib/jenkins/workspace/ 類似于前綴吧桐智。

  • web-deploy 這個(gè)其實(shí)是上面構(gòu)建任務(wù)的名字。

總結(jié):Jenkins 的執(zhí)行目錄是 /var/lib/jenkins/workspace/web-deploy烟馅。也就是說輸入的每一條命令都是在這里面執(zhí)行的说庭。(搞清楚定位能避免好多問題,特別是前端的部署郑趁,就是打包刊驴,移動(dòng),解壓很容易搞錯(cuò)路徑寡润。)

構(gòu)建目標(biāo):偵聽 git 提交到指定分支進(jìn)行構(gòu)建

  • 來到 Jenkins 中選擇 系統(tǒng)管理 -> 系統(tǒng)配置 找到 Jenkins URL 將其復(fù)制捆憎。

  • 隨后在尾部添加 github-webhook/ 尾部斜杠一定不要丟。 整體結(jié)構(gòu)大致為 http://192.168.0.1:8080/github-webhook/

  • 登錄 github 需要集成的項(xiàng)目中添加 webhook悦穿。在 Payload URL 中將上述內(nèi)容填入攻礼。

  • 然后修改 Jenkins 任務(wù)配置 構(gòu)建觸發(fā)器中選擇 GitHub hook trigger for GITScm polling

由于在上面的源碼管理中已經(jīng)指定了main分支,此時(shí)如果這個(gè)分支的代碼有改動(dòng)就會(huì)觸發(fā)自動(dòng)構(gòu)建栗柒。

構(gòu)建目標(biāo):部署到目標(biāo)主機(jī)

在真實(shí)的開發(fā)場(chǎng)景中礁扮,Jenkins 幾乎不會(huì)和前端資源放到一個(gè)服務(wù)器知举。大多數(shù)情況下 Jenkins 所處的服務(wù)器環(huán)境就是一個(gè)工具用的服務(wù)器,放置了一些公司中常用的工具太伊。因此構(gòu)建到指定的服務(wù)器也至關(guān)重要雇锡。

1,系統(tǒng)管理 -> 插件管理 搜索 Publish Over SSH 進(jìn)行安裝僚焦。

2锰提,然后在系統(tǒng)管理 -> 系統(tǒng)配置中找到 Publish over SSH 點(diǎn)擊新增,再點(diǎn)擊高級(jí)芳悲,然后選中 Use password authentication, or use a different key

完成后可點(diǎn)擊右下角 Test Confirguration 進(jìn)行測(cè)試立肘。

3,繼續(xù)修改構(gòu)建任務(wù)名扛。先修改原有的構(gòu)建腳本谅年。因?yàn)橐l(fā)布到遠(yuǎn)程,所以原有的發(fā)布命令要進(jìn)行去除肮韧。

npm install yarn -g
yarn install
yarn build
# 只打包融蹂,然后刪除文件夾。
tar -zcvf dist.tar.gz dist/
rm -rf dist/
復(fù)制代碼

4弄企,選擇構(gòu)建后操作 -> Send build artifacts over SSH

  • Rransfer Set Source files:要上傳到目標(biāo)服務(wù)器的文件超燃。它是一個(gè)相對(duì)路徑,相對(duì)于 Jenkins 的工作目錄 由于上面的 shell 執(zhí)行之后在工作目錄中只有一個(gè)壓縮包拘领,so 直接寫一個(gè)文件名即可意乓。

  • Remove prefix:去前綴。假設(shè)此時(shí)打包文件在 /var/lib/jenkins/workspace/web-deploy/assets/dist.tar.gz院究,那么 Rransfer Set Source files 則應(yīng)該為 assets/dist.tar.gz洽瞬,此時(shí) Remove prefix 配置為 assets/ 則可以去除這個(gè)前綴本涕,否則會(huì)在目標(biāo)服務(wù)中創(chuàng)建 assets 业汰。

  • Remote directory:遠(yuǎn)程的靜態(tài)資源托管目錄。由于配置服務(wù)器默認(rèn)為 /菩颖,所以 usr/share/nginx/html/ 不用以 / 開頭样漆。

  • Exec command:遠(yuǎn)程機(jī)執(zhí)行 shell,由于配置服務(wù)器默認(rèn)為 /晦闰, 所以 工作目錄也是以 / 開始放祟。

執(zhí)行成功后查看執(zhí)行日志會(huì)有類似以下結(jié)果:

SSH: Connecting from host [iZuf6dwyzch3wm3imzxgqfZ]
SSH: Connecting with configuration [aliyun-dev] ...
SSH: EXEC: completed after 202 ms
SSH: Disconnecting configuration [aliyun-dev] ...
# 如果 Transferred 0 file 則需要查看配置的路徑是否正確。表示文件并沒有被移動(dòng)到遠(yuǎn)程主機(jī)中呻右。
SSH: Transferred 1 file(s)
Finished: SUCCESS
復(fù)制代碼

構(gòu)建目標(biāo):釘釘機(jī)器人通知

1跪妥,系統(tǒng)管理 -> 插件管理 搜索 DingTalk 進(jìn)行安裝。文檔

2声滥,釘釘群創(chuàng)建機(jī)器人眉撵。釘釘群 -> 只能群助手 -> 添加機(jī)器人 -> 自定義

3,定義機(jī)器人名字和關(guān)鍵字,創(chuàng)建完成后先將 webhook 中的內(nèi)容復(fù)制纽疟。

4罐韩,Jenkins系統(tǒng)管理 -> 系統(tǒng)配置 -> 釘釘 -> 新增 配置完成后可點(diǎn)擊右下角進(jìn)行測(cè)試。

5污朽,修改構(gòu)建任務(wù)配置散吵。

  • 通知人:atAll 勾選后 @ 不到準(zhǔn)確的人。??蟆肆。輸入框內(nèi)可填寫需要被 @ 人的手機(jī)號(hào)矾睦,多個(gè)換行。

  • 自定義內(nèi)容:支持 markdown 寫法炎功,可以使用一些環(huán)境變量顷锰。192.168.0.1:8080/env-vars.html/

  • 實(shí)現(xiàn)默認(rèn) @ 執(zhí)行人

6,構(gòu)建成功

Pipline 構(gòu)建

上一章節(jié)中著重介紹了如何構(gòu)建 freestyle 的任務(wù)亡问,但是 Jenkins 遠(yuǎn)不止于此官紫。在本章開始之前強(qiáng)烈建議閱讀文檔,重點(diǎn)關(guān)注流水線相關(guān)內(nèi)容州藕。

新建任務(wù) -> 選擇流水線 其他內(nèi)容可以都不用管束世,只關(guān)注流水線 有兩種選擇,演示就選擇第一種床玻。

直接在 Jenkins 中書寫配置毁涉。

在項(xiàng)目的 Jenkinsfile 配置文件中寫配置。

在正式開始之前應(yīng)該了解 Jenkins Pipline 的基礎(chǔ)概念锈死。

pipeline {
    agent any // 在任何可用的代理上贫堰,執(zhí)行流水線或它的任何階段。
    stages {
        stage('Build') { // 定義 "Build" 階段待牵。
            steps {
                // 執(zhí)行與 "Build" 階段相關(guān)的步驟其屏。
            }
        }
        stage('Deploy') { // 定義 "Deploy" 階段。
            steps {
                // 執(zhí)行與 "Deploy" 階段相關(guān)的步驟缨该。
            }
        }
    }
}
  • pipline: 定義流水線整個(gè)結(jié)構(gòu)偎行,可以看做是根節(jié)點(diǎn)

  • agent:指示 Jenkins 為整個(gè)流水線分配一個(gè)執(zhí)行器,比如可以配置 Docker

  • stages:對(duì)整個(gè) CI 流的包裹贰拿,個(gè)人認(rèn)為沒多大用蛤袒,還必須得有。

  • stage: 可以理解為是對(duì)某一個(gè)環(huán)節(jié)的描述膨更。注意:參數(shù)就是描述內(nèi)容妙真,可以是任何內(nèi)容。不要想歪了只能傳遞 Build Deploy 這些荚守。

  • steps: 描述了 stage 中的步驟珍德,可以存在多個(gè)癌椿。

了解到這里還是不夠的。流水線入門 流水線語法參考

Pipline 復(fù)刻 Freestyle

這里先直接把配置貼出來菱阵。后續(xù)結(jié)合內(nèi)容在進(jìn)行分析踢俄。

<details><summary>點(diǎn)擊查看完整配置</summary>

// 自定義 釘釘插件 的 錯(cuò)誤信息和成功信息
def successText = [
    """ ### 新的構(gòu)建信息,請(qǐng)注意查收""",
    """ ${env.JOB_BASE_NAME}任務(wù)構(gòu)建<font color=green>成功</font> 晴及,點(diǎn)擊查看[構(gòu)建任務(wù) #${env.BUILD_NUMBER}](http://106.14.185.47:8080/job/${env.JOB_BASE_NAME}/${env.BUILD_NUMBER}/)"""
]
def failureText = [
    """ ### 新的構(gòu)建信息都办,請(qǐng)注意查收""",
    """ ${env.JOB_BASE_NAME}任務(wù)構(gòu)建<font color=red>失敗</font> ,點(diǎn)擊查看[構(gòu)建任務(wù) #${env.BUILD_NUMBER}](http://106.14.185.47:8080/job/${env.JOB_BASE_NAME}/${env.BUILD_NUMBER}/)"""
]
// 1虑稼,偵聽 github push 事件
properties([pipelineTriggers([githubPush()])])

pipeline {
    agent any
    // 環(huán)境變量定義琳钉。
    environment {
        GIT_REPO = 'http://github.com/vue-ts-vite-temp.git'
    }
    stages {
        // 2,拉取 github 代碼蛛倦,通過 GitSCM 偵聽 push 事件歌懒。
        stage('Pull code') {
            steps {
                checkout(
                    [
                        $class: 'GitSCM',
                        branches: [[name: '*/main']],
                        extensions: [],
                        userRemoteConfigs: [
                            [
                                credentialsId: '381325e4-0f9c-41ea-b5f6-02f8ea2a475a',
                                url: env.GIT_REPO
                            ]
                        ],
                        changelog: true,
                        poll: true,
                    ]
                )
            }
        }
        stage('Install and build') {
            steps {
                // 3,前面安裝過的 nodejs 插件使用
                nodejs('v14.19.0') {
                    sh 'npm install yarn -g'
                    sh 'yarn install'
                    sh 'yarn build'
                }
            }
        }
        stage('Pack') {
            steps {
                sh 'tar -zcvf dist.tar.gz dist/'
                sh 'rm -rf dist/'
            }
        }
        stage('Deploy') {
            steps {
                // 4溯壶,前面下載的 Publish Over SSH 插件的使用
                sshPublisher(
                    publishers: [
                        sshPublisherDesc(
                            configName: 'aliyun-dev',
                            transfers: [
                                sshTransfer(
                                    cleanRemote: false,
                                    excludes: '',
                                    execCommand: '''
                                        cd /usr/share/nginx/html/
                                        tar -zxvf dist.tar.gz
                                        rm -rf dist.tar.gz
                                    ''',
                                    execTimeout: 120000,
                                    flatten: false,
                                    makeEmptyDirs: false,
                                    noDefaultExcludes: false,
                                    patternSeparator: '[, ]+',
                                    remoteDirectory: '/usr/share/nginx/html/',
                                    remoteDirectorySDF: false,
                                    removePrefix: '',
                                    sourceFiles: 'dist.tar.gz'
                                )
                            ],
                            usePromotionTimestamp: false,
                            useWorkspaceInPromotion: false,
                            verbose: false
                        )
                    ]
                )
            }
        }
    }
    post {
        success {
            // 5及皂,DingTalk 插件的使用。
            dingtalk (
                robot: '1314',
                type: 'ACTION_CARD',
                title: 'Jenkins構(gòu)建提醒',
                text: successText,
                btns: [
                    [
                        title: '控制臺(tái)',
                        actionUrl: 'http://106.14.185.11:8080/'
                    ],
                    [
                        title: '項(xiàng)目預(yù)覽',
                        actionUrl: 'http://github.com/'
                    ],
                ],
                at: []
            )
        }
        failure {
            dingtalk(
                robot: '1314',
                type: 'ACTION_CARD',
                title: 'Jenkins構(gòu)建提醒',
                text: failureText,
                btns: [
                    [
                        title: '控制臺(tái)',
                        actionUrl: 'http://106.14.185.11:8080/'
                    ],
                    [
                        title: '項(xiàng)目預(yù)覽',
                        actionUrl: 'http://github.com/'
                    ],
                ],
                at: []// 這里是手機(jī)號(hào)多個(gè)之間,隔開
            )
        }
    }
}

這么多內(nèi)容手寫無疑是很難受的且改,好在 Jenkins 提供了一些幫助工具验烧。訪問地址為:Jenkins地址 + /job + 當(dāng)前任務(wù) + /pipeline-syntax/,例如:http://localhost:8080/job/dev-deploy/pipeline-syntax/又跛,或者進(jìn)入任務(wù)構(gòu)建頁面碍拆,點(diǎn)擊流水線語法進(jìn)入

進(jìn)入該頁面后請(qǐng)熟讀并背誦以下三項(xiàng)。重點(diǎn)放到第一項(xiàng)慨蓝。

回頭看上面的腳本注釋都帶有序號(hào)感混。根據(jù)注釋序號(hào)開始解釋。

1礼烈,在片段生成器中選擇 properties: Set job properties 生成代碼片段弧满。由于只是使用了 git hook trigger 所以要對(duì)生成的片段稍作修改。

2济丘,如果不是為了偵聽 github push 選擇 git: Git 即可谱秽,但現(xiàn)在應(yīng)該選擇 checkout: Check out from version control洽蛀,隨后填寫信息生成代碼即可摹迷。

3,選擇 nodejs: Provide Node & npm bin/folder to Path

4郊供,選擇 sshPublisher: Send build artifacts over SSH峡碉,像上面流水線一樣配置之后直接生成代碼即可。

5驮审,DingTalk 文檔

總結(jié): 通過插件生成的代碼鲫寄,稍作組合就成為了完整的配置吉执。但整體難度還是要略高于 Freestyle 任務(wù)。畢竟生成的代碼有部分也不是拿來即用的地来,并且 Pipline 基本語法一定要有所掌握戳玫。不然生成的代碼都不曉得放到哪里合適。

作者:DoubleX
鏈接:https://juejin.cn/post/7102360505313918983

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末未斑,一起剝皮案震驚了整個(gè)濱河市咕宿,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蜡秽,老刑警劉巖府阀,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異芽突,居然都是意外死亡试浙,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門寞蚌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來田巴,“玉大人,你說我怎么就攤上這事挟秤」潭睿” “怎么了?”我有些...
    開封第一講書人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵煞聪,是天一觀的道長(zhǎng)斗躏。 經(jīng)常有香客問我,道長(zhǎng)昔脯,這世上最難降的妖魔是什么啄糙? 我笑而不...
    開封第一講書人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮云稚,結(jié)果婚禮上隧饼,老公的妹妹穿的比我還像新娘。我一直安慰自己静陈,他們只是感情好燕雁,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著鲸拥,像睡著了一般拐格。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上刑赶,一...
    開封第一講書人閱讀 49,166評(píng)論 1 284
  • 那天捏浊,我揣著相機(jī)與錄音,去河邊找鬼撞叨。 笑死金踪,一個(gè)胖子當(dāng)著我的面吹牛浊洞,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播胡岔,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼法希,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了靶瘸?” 一聲冷哼從身側(cè)響起铁材,我...
    開封第一講書人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎奕锌,沒想到半個(gè)月后著觉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡惊暴,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年饼丘,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片辽话。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡肄鸽,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出油啤,到底是詐尸還是另有隱情典徘,我是刑警寧澤,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布益咬,位于F島的核電站逮诲,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一瑞你、第九天 我趴在偏房一處隱蔽的房頂上張望构捡。 院中可真熱鬧溉委,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至叨叙,卻和暖如春锭弊,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背摔敛。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來泰國打工廷蓉, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人马昙。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓桃犬,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國和親行楞。 傳聞我的和親對(duì)象是個(gè)殘疾皇子攒暇,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

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