云原生網(wǎng)關Traefik和Nginx Proxy Manager初體驗

簡介

Traefik是一個反向代理和負載均衡器谋作,主要用于云原生場景洲鸠,可自動識別Kubernetes疯兼、Docker乔遮、Docker Swarm等等技術下部署的服務扮超,通過label標簽自動生成反向代理路由規(guī)則。Traefik Github倉庫 star是42.6k,官方文檔地址:https://doc.traefik.io/traefik/

Nginx Proxy Manager 基于Nginx提供了一個管理后臺出刷,用戶可以很輕松的對Nginx進行可視化的配置璧疗,內(nèi)置了ssl 證書的自動化生成和管理。NPM Github倉庫star是12.9k馁龟,官方文檔地址:https://nginxproxymanager.com/

初體驗環(huán)境說明

初次使用主要體驗Traefik和NPM的基本功能崩侠,所以使用docker compose 方式快速搭建環(huán)境。

自定義網(wǎng)絡

從 Docker 1.10 版本開始坷檩,docker daemon 實現(xiàn)了一個內(nèi)嵌的 DNS server却音,使容器可以直接通過容器名稱通信,但是需要使用自定義的網(wǎng)絡矢炼。
所以這里我們先創(chuàng)建自定義網(wǎng)絡: custom_net

docker create network custom_network #默認是bridge橋接網(wǎng)絡

當然系瓢,也可以直接在docker compose yaml中定義,讓它自行生成

# 創(chuàng)建自定義網(wǎng)絡
networks:
  custom_net:
    driver: bridge
    name: custom_net

# 引入已創(chuàng)建好的網(wǎng)絡
#networks:
#  custom_net:
#    external: true

Traefik 使用

Traefik的配置分為靜態(tài)配置和動態(tài)配置

  • 靜態(tài)配置一般使用命令行參數(shù)裸删,一次配置后基本不用修改
  • 動態(tài)配置用于配置路由規(guī)則八拱、中間件(處理/轉(zhuǎn)換請求)、負載均衡等涯塔,支持Docker肌稻、File、Ingress匕荸、Consul爹谭、Etcd、ZooKeeper榛搔、Redis诺凡、Http等多種方式

docker compose 配置如下:

version: "3"
services:
  traefik:
    image: traefik:2.9
    command: 
      - "--log.level=DEBUG"
      - "--api.insecure=true"
      - "--api.dashboard=true" 
      - "--providers.docker=true"
      - "--providers.file.directory=/traefik/conf"
      - "--providers.file.watch=true"
      - "--providers.docker.exposedByDefault=false"
    ports:
      # The HTTP port
      - "80:80"
      # The Web UI (enabled by --api)
      - "81:8080"
    environment:
      TZ: Asia/Shanghai
    volumes:
      # So that Traefik can listen to the Docker events
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
      - "/root/docker/traefik/conf:/traefik/conf"
    networks:
      - custom_net

# 引入已創(chuàng)建好的網(wǎng)絡
networks:
  custom_net:
    external: true

配置說明

  1. api.dashboard=true 開啟dashboard管理臺,方便查看生效的配置
  2. providers.docker=true 開啟docker容器label自動感知
  3. providers.docker.exposedByDefault=false 關閉無label的感知
  4. providers.file.watch=true 開啟File文件模式的動態(tài)配置感知
  5. providers.file.directory 配置動態(tài)配置的文件路徑

以上配置主要是方便接下來以Docker和File兩種方式來演示Traefik自動創(chuàng)建路由轉(zhuǎn)發(fā)規(guī)則

Dashboard展示

配置好后yaml后践惑,使用docker compose up -d啟動腹泌,訪問http://localhost:81/dashboard 查看Dashboard面板

2023-04-16_101839.png

  1. Providers中Docker、File說明開啟了這2種動態(tài)配置
  2. Entrypoints的80和8080是Traefik的流量入口
  3. HTTP尔觉、TCP凉袱、UDP三種路由規(guī)則的可視化
  4. Features是Traefik自身的功能:鏈路追蹤、監(jiān)控指標侦铜、訪問日志专甩、Hub擴展能力

Docker label自動感知

以官方的whoami鏡像測試

version: '3'
services:
  whoami:
    # A container that exposes an API to show its IP address
    image: traefik/whoami
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.whoami.rule=PathPrefix(`/test`)"
    networks:
      - custom_net
# 引入已創(chuàng)建好的網(wǎng)絡
networks:
  custom_net:
    external: true

只需要配置lables ,容器啟動后钉稍,Traefik即可自動感知并添加路由轉(zhuǎn)發(fā)規(guī)則 /test -> whoami 容器
PathPrefix匹配以xxx開頭的請求涤躲,更多匹配規(guī)則可查詢Traefik官方-Routers配置

從dashboard中可以看到流量路由的流轉(zhuǎn)情況:
從Traefik的80端口為入口,經(jīng)過/test為前綴匹配的HTTP Router贡未,到達whoami容器服務Service暴露的80端口

image.png

image.png

因為Traefik和whoami同一網(wǎng)絡下(custom_net)种樱,所以whoami不需要對外暴露業(yè)務端口蒙袍,Traefik會自動轉(zhuǎn)到whoami的容器內(nèi)端口。

上面的yaml配置中并沒有暴露whoami的端口

Traefik也可以自動識別多個實例缸托,自動完成負載均衡左敌。
使用docker compose up -d --scale whoami=3 擴容到3個whoami容器,然后多次訪問http://127.0.0.1/test俐镐,從返回的信息里面可以看到會輪詢調(diào)用whoami容器

image.png
image.png
image.png

如果是直接使用docker run啟動容器矫限,可以這樣加label

docker run -d --label 'traefik.http.routers.whoami.rule=PathPrefix(`/test`)' \
 --label traefik.enable=true \
 --network mynet \
 --name whoami-whoami traefik/whoami 

docker compose中啟動的容器名為工程名稱-服務條目名稱-序號,這里--name whoami-whoami 是為了讓docker run啟動的容器自動歸類到上面docker compose啟動的services中

image.png

File配置文件動態(tài)感知

前面介紹了Docker label的方式自動添加路由規(guī)則到Traefik佩抹,現(xiàn)在也介紹一下File文件的方式叼风。
Traefik會自動watch靜態(tài)配置providers.file.directory=/traefik/conf路徑,可以將其掛載出來/root/docker/traefik/conf:/traefik/conf棍苹,然后在conf下新增yaml文件即可

swagger.yaml

http:
  routers:
    s-user:
      service: s-user
      middlewares:
        - "replaceRegex1"
      rule: PathPrefix(`/s-user`)
    s-order:
      service: s-order
      middlewares:
        - "replaceRegex2"
      rule: PathPrefix(`/s-order`)
    s-product:
      service: s-product
      middlewares:
        - "replaceRegex3"
      rule: PathPrefix(`/s-product`)

  middlewares:
    replaceRegex1:
      replacePathRegex:
        regex: "^/s-user/(.*)"
        replacement: "/$1"
    replaceRegex2:
      replacePathRegex:
        regex: "^/s-order/(.*)"
        replacement: "/$1"
    replaceRegex3:
      replacePathRegex:
        regex: "^/s-product/(.*)"
        replacement: "/$1"

  services:
    s-user:
      loadBalancer:
        servers:
        - url: http://swagger-user:8080
    s-order:
      loadBalancer:
        servers:
        - url: http://swagger-order:8080
    s-product:
      loadBalancer:
        servers:
        - url: http://swagger-product:8080

配置解釋:
routers 配置url匹配規(guī)則无宿,PathPrefix是前綴匹配
middlewares 配置中間件,處理url路徑枢里;replacePathRegex是官方提供的用于正則轉(zhuǎn)換孽鸡,以replaceRegex1為例,將/s-user/ 這一段替換為 /
services 配置負載均衡栏豺,swagger-user為docker compose中配置的服務彬碱,利用Docker自帶的DNS功能,通過服務名訪問容器

上面配置的作用:即通過Traefik將80端口的請求url /s-user/xxx 替換為 /xxx 奥洼,轉(zhuǎn)發(fā)到容器內(nèi)部的swagger-user服務的8080端口

示例中的后端服務是3個swagger-ui鏡像服務巷疼,啟動后會讀取xx.json內(nèi)容形成swagger接口文檔,此處不關注xx.json的具體內(nèi)容灵奖,僅作用法參考

version: '3'
services:
  swagger-user:
    image: 'swaggerapi/swagger-ui'
    ports:
      - '8083:8080'
    environment:
      SWAGGER_JSON: /swagger/user.json
    volumes:
      - /mnt/d/docker/swagger-json:/swagger
    networks:
      - custom_net

  swagger-order:
    image: 'swaggerapi/swagger-ui'
    ports:
      - '8085:8080'
    environment:
      SWAGGER_JSON: /swagger/order.json
    volumes:
      - /mnt/d/docker/swagger-json:/swagger
    networks:
      - custom_net

  swagger-product:
    image: 'swaggerapi/swagger-ui'
    ports:
      - '8084:8080'
    environment:
      SWAGGER_JSON: /swagger/product.json
    volumes:
      - /mnt/d/docker/swagger-json:/swagger
    networks:
      - custom_net

networks:
  custom_net:
    external: true

其他動態(tài)配置如使用Etcd嚼沿、Consul、ZooKeeper瓷患,配置格式與File類似骡尽。
File文件配置支持Traefik和業(yè)務服務都不重啟的情況下動態(tài)生效路由配置,F(xiàn)ile watch底層是使用fsnotify擅编,對于少數(shù)系統(tǒng)不支持動態(tài)感知爆阶,如windows wsl ubuntu

Nginx Proxy Manager 使用

NPM需要用到數(shù)據(jù)庫來存儲代理轉(zhuǎn)發(fā)規(guī)則等數(shù)據(jù),控制臺支持禁用某個路由轉(zhuǎn)發(fā)規(guī)則沙咏,其實就是通過數(shù)據(jù)庫來暫存配置數(shù)據(jù)實現(xiàn)。
這里直接使用MySQL來初體驗班套。docker-compose.yaml內(nèi)容如下:

version: '3'
services:
  nginx-proxy-manager:
    image: 'jc21/nginx-proxy-manager:latest'
    restart: always
    ports:
      # These ports are in format <host-port>:<container-port>
      - '80:80' # Public HTTP Port
      - '443:443' # Public HTTPS Port
      - '81:81' # Admin Web Port
      # Add any other Stream port you want to expose
      # - '21:21' # FTP
    environment:
      # Mysql/Maria connection parameters:
      DB_MYSQL_HOST: mysql
      DB_MYSQL_PORT: 3306
      DB_MYSQL_USER: "npm"
      DB_MYSQL_PASSWORD: "npm"
      DB_MYSQL_NAME: "npm"
      # Uncomment this if IPv6 is not enabled on your host
      # DISABLE_IPV6: 'true'
      TZ: Asia/Shanghai
    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt
    networks:
      - custom_net
    depends_on:
      - mysql

  mysql:
    image: mysql:5.7.16
    container_name: mysql
    restart: always
    ports:
      - "3306:3306"
    volumes:
      - /mnt/d/docker/docker-compose/mysql/data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: "123456"
      TZ: Asia/Shanghai
    #最大內(nèi)存限制
    deploy:
      resources:
        limits:
          memory: 256M
    networks:
      - custom_net
    privileged: true
    command:
      --server_id=100
      --log-bin=mysql-bin
      --binlog_format=mixed
      --expire_logs_days=7
      --default-authentication-plugin=mysql_native_password
      --character-set-server=utf8mb4
      --collation-server=utf8mb4_general_ci
      --max_allowed_packet=16M
      --sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
      --max_connections=10000
      --slow_query_log=ON
      --long_query_time=1
      --log_queries_not_using_indexes=ON
      --lower_case_table_names=1
      --explicit_defaults_for_timestamp=true

# 引入已創(chuàng)建好的網(wǎng)絡
networks:
  custom_net:
    external: true

使用docker compose up -d啟動后肢藐,記得先進入MySQL創(chuàng)建用戶、賬號吱韭、密碼吆豹、數(shù)據(jù)庫鱼的,都是叫npm

可以通過NPM環(huán)境變量中的DB_MYSQL_USER、DB_MYSQL_NAME等配置自行指定
因為在同一容器網(wǎng)絡下DB_MYSQL_HOST可以直接使用mysql訪問

啟動完成后痘煤,可以訪問localhost:81 進入控制臺凑阶,首次登錄需要修改賬號/密碼。默認的賬號/密碼是admin@example.com/changeme

以whoami為例衷快,配置路由規(guī)則接收來源是localhost宙橱、url是/test開頭的請求

測試環(huán)境是windows wsl ubuntu環(huán)境,所以使用localhost蘸拔,如果是云服務器师郑,直接填寫其公網(wǎng)ip即可

image.png

然后在Custom locations里面添加一個location

image.png

因為之前已經(jīng)啟動了多個whoami容器,所以此時可以直接訪問http://localhost/test调窍,多次訪問也是輪詢調(diào)用多個容器實例

配置靜態(tài)資源

既然是基于Nginx實現(xiàn)宝冕,那么NPM肯定可以配置靜態(tài)資源訪問,這也是NPM和Traefik的一個區(qū)別邓萨,Traefik更多是做反向代理的用途地梨。
上面已經(jīng)把data目錄掛載出來了,所以可以直接在data目錄下新建test目錄缔恳,新增123.txt宝剖、test.html文件
接下來在控制臺配置靜態(tài)資源訪問,配置入口:Proxy Host -> Advanced -> Custom Nginx Configuration

location /files {
  alias /data/html/;
  autoindex on;
}
image.png

然后訪問 http://localhost/files/

image.png

也可以直接訪問 http://localhost/files/123.txt 查看文件內(nèi)容

配置upstream負載均衡

upstream在Nginx中配置示例如下:

upstream backend {
    server backend1.example.com:8080;
    server backend2.example.com:8080;
}
server {
    location / {
        proxy_pass http://backend;
    }
}

直接在NPM控制臺的location里面配置不了upstream褐耳,我們可以找到其提供的自定義配置入口诈闺。
通過查閱NPM官方文檔-高級配置,可以知道自定義配置路徑是 /data/nginx/custom
其中http塊配置可以用下面2個铃芦,選其一即可

/data/nginx/custom/http_top.conf #包含在主 http 塊的頂部
/data/nginx/custom/http.conf #包含在主 http 塊的末尾
  1. 在掛載路徑 data/nginx下新建custom目錄雅镊,在下面新建http.conf文件
upstream whoami-upstream {
  server 172.19.0.3:80;
  server 172.19.0.4:80;
  server 172.19.0.5:80;
}

這里直接配置whoami的容器ip,方便測試

  1. 在控制臺Advanced配置里自定義 location
location /test-lb {
   proxy_pass http://whoami-upstream;
}
N2.png

然后訪問 http://localhost/test-lb 測試刃滓,請求仍然會輪詢調(diào)用whoami服務仁烹。

NPM實現(xiàn)原理

既然NPM是基于Nginx,那么只要找到Nginx的默認配置咧虎,即可知道它的實現(xiàn)原理卓缰。本質(zhì)上是對Nginx配置的管理。
執(zhí)行docker compose logs砰诵,從NPM的啟動日志可以看到默認的配置路徑:

nginx-proxy-manager-nginx-proxy-manager-1  | - /etc/nginx/conf.d/production.conf
nginx-proxy-manager-nginx-proxy-manager-1  | - /etc/nginx/conf.d/include/ssl-ciphers.conf
nginx-proxy-manager-nginx-proxy-manager-1  | - /etc/nginx/conf.d/include/proxy.conf
nginx-proxy-manager-nginx-proxy-manager-1  | - /etc/nginx/conf.d/include/force-ssl.conf
nginx-proxy-manager-nginx-proxy-manager-1  | - /etc/nginx/conf.d/include/block-exploits.conf
nginx-proxy-manager-nginx-proxy-manager-1  | - /etc/nginx/conf.d/include/assets.conf
nginx-proxy-manager-nginx-proxy-manager-1  | - /etc/nginx/conf.d/include/letsencrypt-acme-challenge.conf
nginx-proxy-manager-nginx-proxy-manager-1  | - /etc/nginx/conf.d/include/ip_ranges.conf
nginx-proxy-manager-nginx-proxy-manager-1  | - /etc/nginx/conf.d/include/resolvers.conf
nginx-proxy-manager-nginx-proxy-manager-1  | - /etc/nginx/conf.d/default.conf

執(zhí)行docker compose exec nginx-proxy-manager bash 進入容器征唬,查看對應的conf文件內(nèi)容
default.conf默認監(jiān)聽80、443端口(處理轉(zhuǎn)發(fā)請求)茁彭,production.conf默認監(jiān)聽81端口(處理控制臺請求)

nginx主配置文件

路徑:/etc/nginx/nginx.conf
內(nèi)容如下:

# run nginx in foreground
daemon off;
pid /run/nginx/nginx.pid;
user npmuser;

# Set number of worker processes automatically based on number of CPU cores.
worker_processes auto;

# Enables the use of JIT for regular expressions to speed-up their processing.
pcre_jit on;

error_log /data/logs/fallback_error.log warn;

# Includes files with directives to load dynamic modules.
include /etc/nginx/modules/*.conf;

events {
        include /data/nginx/custom/events[.]conf;
}

http {
        include                       /etc/nginx/mime.types;
        default_type                  application/octet-stream;
        sendfile                      on;
        server_tokens                 off;
        tcp_nopush                    on;
        tcp_nodelay                   on;
        client_body_temp_path         /tmp/nginx/body 1 2;
        keepalive_timeout             90s;
        proxy_connect_timeout         90s;
        proxy_send_timeout            90s;
        proxy_read_timeout            90s;
        ssl_prefer_server_ciphers     on;
        gzip                          on;
        proxy_ignore_client_abort     off;
        client_max_body_size          2000m;
        server_names_hash_bucket_size 1024;
        proxy_http_version            1.1;
        proxy_set_header              X-Forwarded-Scheme $scheme;
        proxy_set_header              X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header              Accept-Encoding "";
        proxy_cache                   off;
        proxy_cache_path              /var/lib/nginx/cache/public  levels=1:2 keys_zone=public-cache:30m max_size=192m;
        proxy_cache_path              /var/lib/nginx/cache/private levels=1:2 keys_zone=private-cache:5m max_size=1024m;

        log_format proxy '[$time_local] $upstream_cache_status $upstream_status $status - $request_method $scheme $host "$request_uri" [Client $remote_addr] [Length $body_bytes_sent] [Gzip $gzip_ratio] [Sent-to $server] "$http_user_agent" "$http_referer"';
        log_format standard '[$time_local] $status - $request_method $scheme $host "$request_uri" [Client $remote_addr] [Length $body_bytes_sent] [Gzip $gzip_ratio] "$http_user_agent" "$http_referer"';

        access_log /data/logs/fallback_access.log proxy;

        # Dynamically generated resolvers file
        include /etc/nginx/conf.d/include/resolvers.conf;

        # Default upstream scheme
        map $host $forward_scheme {
                default http;
        }

        # Real IP Determination

        # Local subnets:
        set_real_ip_from 10.0.0.0/8;
        set_real_ip_from 172.16.0.0/12; # Includes Docker subnet
        set_real_ip_from 192.168.0.0/16;
        # NPM generated CDN ip ranges:
        include conf.d/include/ip_ranges.conf;
        # always put the following 2 lines after ip subnets:
        real_ip_header X-Real-IP;
        real_ip_recursive on;

        # Custom
        include /data/nginx/custom/http_top[.]conf;

        # Files generated by NPM
        include /etc/nginx/conf.d/*.conf;
        include /data/nginx/default_host/*.conf;
        include /data/nginx/proxy_host/*.conf;
        include /data/nginx/redirection_host/*.conf;
        include /data/nginx/dead_host/*.conf;
        include /data/nginx/temp/*.conf;

        # Custom
        include /data/nginx/custom/http[.]conf;
}

stream {
        # Files generated by NPM
        include /data/nginx/stream/*.conf;

        # Custom
        include /data/nginx/custom/stream[.]conf;
}

# Custom
include /data/nginx/custom/root[.]conf;

從include順序可以知道总寒,它在http塊中先是include /data/nginx/custom/http_top[.]conf
然后 include /data/nginx/proxy_host/*.conf,而控制臺對應的配置就在這個data/nginx目錄
最后include /data/nginx/custom/http[.]conf理肺。這樣也就對應了官方文檔說明的:

/data/nginx/custom/http_top.conf #包含在主 http 塊的頂部
/data/nginx/custom/http.conf #包含在主 http 塊的末尾

自定義配置

以代理配置為例摄闸,查看data/nginx/proxy_host 目錄下有一個 1.conf善镰,其內(nèi)容即對應我們的自定義配置

# ------------------------------------------------------------
# localhost
# ------------------------------------------------------------
server {
  set $forward_scheme http;
  set $server         "127.0.0.1";
  set $port           80;

  listen 80;
listen [::]:80;

  server_name localhost;


location /files {
  alias /data/html/;
  autoindex on;
}
location /test-lb {
   proxy_pass http://whoami-upstream;
}

  location /test {
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Scheme $scheme;
    proxy_set_header X-Forwarded-Proto  $scheme;
    proxy_set_header X-Forwarded-For    $remote_addr;
    proxy_set_header X-Real-IP      $remote_addr;
    proxy_pass       http://whoami:80;

  # Block Exploits
  include conf.d/include/block-exploits.conf;
  }

  location / {
    # Proxy!
    include conf.d/include/proxy.conf;
  }
  # Custom
  include /data/nginx/custom/server_proxy[.]conf;
}

可以看到,它實際是把Proxy Host 中 Custom locations 年枕、Advanded配置合并了炫欺。

至此,Traefik和Nginx Proxy Manager的初體驗就結(jié)束了~

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末熏兄,一起剝皮案震驚了整個濱河市品洛,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌霍弹,老刑警劉巖毫别,帶你破解...
    沈念sama閱讀 216,651評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異典格,居然都是意外死亡岛宦,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評論 3 392
  • 文/潘曉璐 我一進店門耍缴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來砾肺,“玉大人,你說我怎么就攤上這事防嗡”渫簦” “怎么了?”我有些...
    開封第一講書人閱讀 162,931評論 0 353
  • 文/不壞的土叔 我叫張陵蚁趁,是天一觀的道長裙盾。 經(jīng)常有香客問我,道長他嫡,這世上最難降的妖魔是什么番官? 我笑而不...
    開封第一講書人閱讀 58,218評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮钢属,結(jié)果婚禮上徘熔,老公的妹妹穿的比我還像新娘。我一直安慰自己淆党,他們只是感情好酷师,可當我...
    茶點故事閱讀 67,234評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著染乌,像睡著了一般山孔。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上荷憋,一...
    開封第一講書人閱讀 51,198評論 1 299
  • 那天饱须,我揣著相機與錄音,去河邊找鬼台谊。 笑死蓉媳,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的锅铅。 我是一名探鬼主播酪呻,決...
    沈念sama閱讀 40,084評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼盐须!你這毒婦竟也來了玩荠?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,926評論 0 274
  • 序言:老撾萬榮一對情侶失蹤贼邓,失蹤者是張志新(化名)和其女友劉穎阶冈,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體塑径,經(jīng)...
    沈念sama閱讀 45,341評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡女坑,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,563評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了统舀。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片匆骗。...
    茶點故事閱讀 39,731評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖誉简,靈堂內(nèi)的尸體忽然破棺而出碉就,到底是詐尸還是另有隱情,我是刑警寧澤闷串,帶...
    沈念sama閱讀 35,430評論 5 343
  • 正文 年R本政府宣布瓮钥,位于F島的核電站,受9級特大地震影響烹吵,放射性物質(zhì)發(fā)生泄漏碉熄。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,036評論 3 326
  • 文/蒙蒙 一年叮、第九天 我趴在偏房一處隱蔽的房頂上張望具被。 院中可真熱鬧,春花似錦只损、人聲如沸一姿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽叮叹。三九已至,卻和暖如春爆存,著一層夾襖步出監(jiān)牢的瞬間蛉顽,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評論 1 269
  • 我被黑心中介騙來泰國打工先较, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留携冤,地道東北人悼粮。 一個月前我還...
    沈念sama閱讀 47,743評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像曾棕,于是被迫代替她去往敵國和親扣猫。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,629評論 2 354

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