9. Gitlab

1. Gitlab介绍

  • git: 分布式存储的后端服务
  • gitlab: 是一个基于git的安装程序, 可以实现公司私有的持续集成服务
  • github: 一个基于git开源网站, 开发爱好者和第三方开源项目会把源代码提交到github进行开源

部署Gitlab的资源建议:

虚拟机或物理机: 

cpu: 8c, 16c, 更高
内存: 16g, 32g, 更高
硬盘: 根据代码数据量配置, Intel企业级硬盘, PCI-E或者SSD

上百人公司: 一般16c, 32g即可, 硬盘前期建议2T, 之后进行数据量评估

2. Gitlab安装及配置

安装包下载地址: https://packages.gitlab.com/gitlab/gitlab-ce
rpm清华源下载地址: https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/
ubuntu清华源下载地址: https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/ubuntu/pool/

实验环境:

Ubuntu-1804
10.0.0.239
gitlab-ce_13.6.3-ce.0_amd64.deb

2.1 Gitlab安装

[root@gitlab:~]# ls
gitlab-ce_13.6.3-ce.0_amd64.deb
[root@gitlab:~]# apt update
[root@gitlab:~]# dpkg -i gitlab-ce_13.6.3-ce.0_amd64.deb

2.2 Gitlab配置

[root@gitlab:~]# vim /etc/gitlab/gitlab.rb
external_url 'http://10.0.0.239' # 配置web访问的地址, 如果企业内部有DNS服务, 可以用域名, 或者直接写gitlab服务器的ip地址
# 可选邮件通知配置, gitlab会向管理员和用户发送通知邮件
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "smtp.qq.com"
gitlab_rails['smtp_port'] = 465
gitlab_rails['smtp_user_name'] = "953260716@qq.com"
gitlab_rails['smtp_password'] = "ihrdeonfluskbdhb"
gitlab_rails['smtp_domain'] = "qq.com"
gitlab_rails['smtp_authentication'] = :login
gitlab_rails['smtp_enable_starttls_auto'] = true
gitlab_rails['smtp_tls'] = true
gitlab_rails['gitlab_email_from'] = "953260716@qq.com"
user["git_user_email"] = "953260716@qq.com"

使用客户端命令, gitlab-ctl configure, 重新加载配置文件

注意: 第一次配置Gitlab, 和之后每次修改Gitlab配置文件, 都需要重新加载配置文件

[root@gitlab:~]# gitlab-ctl reconfigure

启动gitlab

[root@gitlab:~]# gitlab-ctl start

2.3 Gitlab相关目录介绍

/etc/gitlab # 配置文件目录, 必须做定期备份
/run/gitlab # 运行pid目录
/opt/gitlab # 安装目录, 备份一次即可
/var/opt/gitlab # 数据目录, 必须做定期备份, 开发上传的代码都会存在这个目录里
/var/log/gitlab # 日志目录

2.4 登录Gitlab, 初始化管理员密码

账号: root
密码: 自己定义

2.5 取消匿名用户注册并且设置中文字体

默认情况下, 任何用户都可以登录Gitlab进行注册. 必须取消该功能, 所有账号的权限开启都由运维人员手动设置

image.png

取消Sign-up enabled, 点击Save Changed即可

image.png

点击右上角图标, 选择Settings, 在左侧列表选择Preferences, 在Location中选择字体, 点击Save Changed即可.

重新登录, 可以看到注册功能已经关闭, 并且字体设置为中文

2.6 Gitlab常用命令

gitlab-rails # 用于启动控制台进行特殊操作, 比如修改管理员密码, 打开数据库控制台
gitlab-rails dbconsole # 进入gitlab数据库
gitlab-psql # 进入数据库命令行
gitlab-rake #  数据备份恢复等数据操作
gitlab-ctl #客户端命令行操作行
gitlab-ctl stop # 停止 gitlab
gitlab-ctl start # 启动 gitlab
gitlab-ctl restart # 重启 gitlab
gitlab-ctl status [组件名称] # 查看组件运行状态, 可以查看gitlab每个组件
gitlab-ctl tail nginx # 查看某个组件的日志, 可以用于排错

2.7 用户, 组和项目管理

  • User: 开发人员, 后期用于代码提交和回滚
  • Project: 一个项目会包含很多功能, 每个功能都可以认为是一个project
  • Group: 一个组, 一个组就是一个项目, 这个项目内会有多个服务(Project)

先创建组, 再创建Project, 比如: QQ项目就是一个Group, 这个Group里有不同的Project来实现不同的功能

10.0.0.239/QQ/聊天
10.0.0.239/QQ/传输文件
10.0.0.239/QQ/QQ群
...

2.7.1 用户创建

登录到gitlab主页面后, 点击上方设置按钮, 进入设置页面

image.png

选择New User

image.png

填写用户信息, 之后点创建用户

image.png

用户会收到gitlab发送的邮件, 修改密码后即可登录

非管理员用户是没有gitlab设置权限的, 登录后只能看到自己被允许看到和编辑的项目

image.png

2.7.2 组创建

组一般由开发人员自行创建, 运维人员只需创建用户即可

普通用户登录后, 选择创建组

image.png

填写组信息, 选择private权限, 只允许被添加到该组的成员可以访问该组的信息

image.png

2.7.3 项目创建

进入到组后, 选择创建项目

image.png

填写项目信息, 选择private权限

image.png

2.8 添加文件

2.8.1 添加一个README文件

进入到某个项目, 选择添加README文件

image.png

编辑文件内容后, 选择左下角commit

image.png

编辑commit注释, 点击commit

image.png

回到web-01项目, 查看文件commit成功

image.png

2.9 组权限管理

可以由运维管理, 也可以由组的创建者管理

2.9.1 创建一个新用户

2.9.2 将新用户添加到qq组里

可以从Dashboard选择需要管理的组

image.png

选择需要添加用户

image.png

根据需要选择权限

image.png

点击将用户添加到组

image.png

3. Gitlab使用

准备一台客户机, 安装git命令

Ubuntu-1804
10.0.0.229
[root@git-client:~]# apt update
[root@git-client:~]# apt install git -y

在qq组, 创建一个新的project, web-02

在web-02创建一个index.html文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>qq</title>
</head>
<body>
<h1>web-02-v.111111</h1>h1>
</body>
</html>

3.1 项目克隆

进到对应的项目下

image.png

可以通过SSH克隆, 也可以通过http克隆

image.png

克隆项目文件需要先选择目标目录, 这里clone到/opt下

3.1.1 使用http克隆

[root@git-client:~]# cd /opt
[root@git-client:/opt]# git clone http://10.0.0.239/qq/web-02.git
Cloning into 'web-02'...
Username for 'http://10.0.0.239': developer-01
Password for 'http://developer-01@10.0.0.239': 
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), done.

克隆的项目会保存在当前目录的对应项目名字的目录里

[root@git-client:/opt]# ls
web-02

3.1.2 本地修代码后, 本地commit

[root@git-client:/opt]# cd web-02/
[root@git-client:/opt/web-02]# ls
index.html
[root@git-client:/opt/web-02]# vim index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>qq</title>
</head>
<body>
<h1>web-02-v.111111</h1> # 修改上面错误的代码
<h1>web-02-v.222222</h1>     # 添加一行代码, 模拟升级版本                                            
</body>
</html>
[root@git-client:/opt/web-02]# git add . # "." 表示把当前目录下所有文件都提交到暂存区, 也可以指定某个文件
root@git-client:/opt/web-02# git config --global user.email "anshan0810@icloud.com"
root@git-client:/opt/web-02# git config --global user.name "developer-01"
[root@git-client:/opt/web-02]# git commit -m "v2" # -m 将暂存区的文件提交到本地仓库, 并给提交添加注释说明
[master 94a51f5] v2
 1 file changed, 2 insertions(+), 1 deletion(-)

3.1.3 将本地commit推送到gitlab

[root@git-client:/opt/web-02]# git push -u origin
Username for 'http://10.0.0.239': developer-01
Password for 'http://developer-01@10.0.0.239': 
Counting objects: 3, done.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 279 bytes | 279.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0)
To http://10.0.0.239/qq/web-02.git
   2930448..94a51f5  master -> master

补充: 如果本地commit时, 提示如下报错, 需要修改工程目录下的.git/config文件, 添加一个邮箱和名字. 无需reconfigure gitlab, 立即生效

[root@git-client:/opt/web-02]# git add ./index.html 
[root@git-client:/opt/web-02]# git commit -m "v2"

*** Please tell me who you are.

Run

  git config --global user.email "you@example.com"
  git config --global user.name "Your Name"

to set your account's default identity.
Omit --global to set the identity only in this repository.

fatal: unable to auto-detect email address (got 'root@git-client.(none)')
[root@git-client:/opt/web-02]# cd .git
[root@git-client:/opt/web-02/.git]# vim config 
...
[user]
    email = developer-01@qq.com # 添加的邮箱和名字不起实际作用, 只会在gitlab上显示本次提交的用户名 一般写成自己的gitlab用户名和邮箱就行, 便于统计
    name = developer-01

3.1.4 验证提交成功

image.png
image.png
image.png

3.1.5 运行提交的代码, 测试其可用

3.1.5.1 搭建一个apache服务器

[root@git-client:~]# apt -y install apache2

3.1.5.2 将提交的代码克隆到apache的页面目录

[root@git-client:~]# cd /var/www/html
[root@git-client:/var/www/html]# git clone http://10.0.0.239/qq/web-02.git
Cloning into 'web-02'...
Username for 'http://10.0.0.239': developer-01
Password for 'http://developer-01@10.0.0.239': 
remote: Enumerating objects: 6, done.
remote: Counting objects: 100% (6/6), done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 6 (delta 1), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (6/6), done.

3.1.5.3 测试访问

image.png

补充: 如果代码更新到gitlab后, 可以直接在工程目录, 这里就是web-02目录下, 执行git pull命令, 把新的代码clone到本地, 即可完成代码的更新. 因此, 对于静态的资源, 比如html页面, 图片等, 和php这些无需编译的代码, 都可以采用此方法. 开发将代码push到gitlab后, 直接在项目目录下执行git pull把最新的代码clone下来, 即可完成更新

3.2 gitlab的数据保存

svn与csv的数据保存

每次提交的文件都会单独保存, 即按照文件的提交时间, 区分不同的版本, 保存至不同的逻辑存储区域, 后期恢复的时候直接基于版本恢复

gitlab的数据保存

gitlab与svn的数据保存方式不一样, gitlab虽然也会在内部对数据进行逻辑划分, 保存, 但是当后期提交的数据如果和之前提交过的数据没有变化, 其会直接快照之前的文件, 而不是在将文件重新上传一份再保存一遍, 这样既节省了空间, 又加快了代码提交速度

gitlab中, 如果一个文件没有改变, 那么新版本会和老版本建立一个类似软连接, 直接调用老版本, 而不是重新把没有改变的老版本再上传一份. 如果文件做了修改, 那么就是直接上传一份新的版本

image.png

3.3 常用git命令

使用git命令下载代码与提交代码等操作

image.png

代码克隆到开发本地的工作目录后, 这个目录就是工作区. 在工程目录下, 开发编辑代码后, 使用git add命令, 可以把文件加入到版本库, 这个版本库是本地版本库, 然后使用commit命令将文件提交到本地仓库. master指的就是开发自己本地的版本库. 在本地提交后, 可以在本地回滚.

git config --global user.name “name“ #设置全局用户名
git config --global user.email xxx@xx.com #设置全局邮箱
git config --global --list #列出用户全局设置
git add index.html / . #添加指定文件、目录或当前目录下所有数据到暂存区
git commit -m “11“ #提交文件到工作区
git status #git status命令用于显示工作目录和暂存区的状态。使用此命令能看到那些修改被暂存到了, 哪些没有, 哪些文件没有被Git tracked到。git status不显示已经commit到项目历史中去的信息
git push #提交代码到服务器
git pull #获取代码到本地, 前提是之前已经clone过相同的项目到本地
git log #查看操作日志
vim .gitignore #定义忽略文件上传至 gitlab
git reset --hard HEAD^^ #git 版本回滚, HEAD 为当前版本,加一个^为上一个,^^为上上一个
#版本. git reset回滚会直接回滚本地项目工程中的代码, 而不是gitlab上的代码. 如果需要回滚静态页面, 可以直接在服务器利用git reset进行回滚. 回滚时需要登录到生产服务器,到项目目录下去回滚
git reflog # #获取每次提交的 ID,可以使用--hard 根据提交的 ID 进行版本回退
git reset --hard 5ae4b06 #回退到指定 id 的版本, 先通过git log获取每次提交的id
git branch #查看当前所处的分支
git checkout -b develop #创建并切换到一个新分支
git checkout develop #切换分支
git show #显示当前工程所处的版本
  • 回滚静态文件案例

当前处于v4版本, 假设需要回滚到v3版本

图片.png
  • 如果是回滚服务器上的代码, 需要到服务器项目页面进行回滚
root@git-client:/var/www/html/web-02# git reset --hard HEAD^
HEAD is now at eb18ca1 v3
图片.png
  • 回滚后, gitlab上的代码是不会回滚的, 工作中一般都是配合多分支, 实现master生产分支和develop开发分支隔离, 并且在生产分支添加tag标签, 基于版本标签进行部署和回滚. 这样可以保留每个版本的代码提交

3.4 git缓存区和工作区等概念

工作区: clone的代码或者开发自己编写的代码文件所在的目录, 通常是代码所在的一个服务的目录名称.

暂存区: 用于存储在工作区中对代码进行修改后的文件所保存的地方, 使用git add添加.

本地仓库: 用于提交存储在工作区和暂存区中改过的文件的地方, 使用git commit提交

远程仓库: 多个开发共同协作提交代码的仓库, 即gitlab服务器. 之后由Jenkins完成代码部署

image.png

3.5 gitlab多分支

这个分支是在开发机创建, 写完代码把分支推送到gitlab项目, 等分支项目完成, 会合并最新的master的代码进行测试, 测试通过, master会合并该分支, 进行上线

通过多分支, 来控制代码质量, 确保部署到生成环境的代码都是经过测试无误的代码

master: 会部署到生成环境的代码会放到master

项目开始会创建master分支, 存放没有bug的代码, 开发会创建单独的开发分支, 存开发提交的代码, 开发完毕后, 会把master的代码合并到开发分支, 这样就是最新的代码了, 之后部署到测试环境进行测试, 经过多次确保无误后, 再把开发分支的代码合并到master, 用于生产环境的部署. (一般由开发部门负责人进行合并)

3.6 gitlab数据备份和恢复

3.6.1 停止gitlab数据写入服务

备份时不能停止整个gitlab服务, 因为备份还需要gitlab, 只需要停止unicorn和sidekiq即可

root@gitlab:~# gitlab-ctl stop unicorn
root@gitlab:~# gitlab-ctl stop sidekiq
ok: down: sidekiq: 1s, normally up

3.6.2 使用gitlab-rake备份数据

root@gitlab:~# gitlab-rake gitlab:backup:create

备份后的文件, 以Unix时间戳开头, 是一个tar包

root@gitlab:~# ll /var/opt/gitlab/backups/
total 260
drwx------  2 git  root   4096 Jul  1 18:51 ./
drwxr-xr-x 21 root root   4096 Jun 30 23:10 ../
-rw-------  1 git  git  256000 Jul  1 18:51 1625136696_2021_07_01_13.6.3_gitlab_backup.tar

3.6.3 备份后, 启动gitlab

root@gitlab:~# gitlab-ctl start
  • 查看当前的版本, v4
图片.png
  • 提交两个新版本, v5和v6, 再做一次备份
root@git-client:/opt/web-02# vim index.html 
root@git-client:/opt/web-02# git add .
root@git-client:/opt/web-02# git commit -m "v5"
[master bce48d7] v5
 1 file changed, 1 insertion(+)
root@git-client:/opt/web-02# git push -u origin
Username for 'http://10.0.0.239': developer-01     
Password for 'http://developer-01@10.0.0.239': 
Counting objects: 3, done.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 300 bytes | 300.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0)
To http://10.0.0.239/qq/web-02.git
   5c45381..bce48d7  master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.
root@git-client:/opt/web-02# vim index.html 
root@git-client:/opt/web-02# git add .
root@git-client:/opt/web-02# git commit -m "v6"
[master 48da23d] v6
 1 file changed, 1 insertion(+)
root@git-client:/opt/web-02# git push -u origin
Username for 'http://10.0.0.239': developer-01
Password for 'http://developer-01@10.0.0.239': 
Counting objects: 3, done.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 283 bytes | 283.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0)
To http://10.0.0.239/qq/web-02.git
   bce48d7..48da23d  master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.

  • 当前版本为v6
图片.png
  • 进行备份
root@gitlab:~# gitlab-ctl stop unicorn
root@gitlab:~# gitlab-ctl stop sidekiq
ok: down: sidekiq: 1s, normally up
root@gitlab:~# gitlab-rake gitlab:backup:create
root@gitlab:~# ll /var/opt/gitlab/backups/
total 512
drwx------  2 git  root   4096 Jul  1 19:28 ./
drwxr-xr-x 21 root root   4096 Jun 30 23:10 ../
-rw-------  1 git  git  256000 Jul  1 18:51 1625136696_2021_07_01_13.6.3_gitlab_backup.tar # v4的备份
-rw-------  1 git  git  256000 Jul  1 19:28 1625138934_2021_07_01_13.6.3_gitlab_backup.tar # v6的备份

3.6.4 执行还原

  • 删除index.html文件, 当前处于v6版本
图片.png
  • 停止服务
root@gitlab:~# gitlab-ctl stop unicorn
root@gitlab:~# gitlab-ctl stop sidekiq
ok: down: sidekiq: 1767s, normally up
  • 确认需要恢复的文件
root@gitlab:~# ll /var/opt/gitlab/backups/
total 512
drwx------  2 git  root   4096 Jul  1 19:28 ./
drwxr-xr-x 21 root root   4096 Jun 30 23:10 ../
-rw-------  1 git  git  256000 Jul  1 18:51 1625136696_2021_07_01_13.6.3_gitlab_backup.tar #v4版本
-rw-------  1 git  git  256000 Jul  1 19:28 1625138934_2021_07_01_13.6.3_gitlab_backup.tar #v6版本
  • 恢复数据到v6版本
# 恢复时, 文件只需要写到gitlab版本即可
root@gitlab:~# gitlab-rake gitlab:backup:restore BACKUP=1625138934_2021_07_01_13.6.3
  • 启动服务
root@gitlab:~# gitlab-ctl start sidekiq
root@gitlab:~# gitlab-ctl start unicorn
  • 验证数据恢复
图片.png

3.6.5 需要备份的文件和备份策略

    1. gitlab数据
使用gitlab-rake命令进行备份, 一般建议通过计划任务, 每天凌晨备份一次. 根据公司情况, 指定保留几份最近的数据
数据备份后, 可以传到存储设备, 或者直接把/var/opt/gitlab/backups目录挂载一个存储
需要注意的是, gitlab并没有实时备份功能, 一旦在两次备份期间数据操作错误, 只能还原到最近的一次备份, 或者由开发人员在本地git仓库查找文件, 然后重新上传到gitlab
    1. 服务的配置文件
gitlab由多个组件组成, 比如nginx. 这些配置文件, 包括gitlab本身的配置文件, 需要执行备份.
一般是在服务搭建好后, 做一次备份, 之后每次配置文件修改再备份一次

/etc/gitlab/gitlab.rb # gitlab的配置文件
/var/opt/gitlab/nginx/conf/ # nginx的配置文件存放目录, 需要备份整个目录

root@gitlab:~# ll /var/opt/gitlab/nginx/conf/
total 28
drwxr-x--- 2 root gitlab-www 4096 Jun 30 23:10 ./
drwxr-x--- 9 root gitlab-www 4096 Jul  1 17:25 ../
-rw-r--r-- 1 root root        902 Jun 30 02:33 gitlab-health.conf
-rw-r--r-- 1 root root       4264 Jun 30 02:33 gitlab-http.conf
-rw-r--r-- 1 root root       3045 Jun 30 02:33 nginx.conf
-rw-r--r-- 1 root root        603 Jun 30 02:33 nginx-status.conf
    1. gitlab秘钥文件
秘钥文件只在本机生效, 因此, 备份后也只能还原到当前服务器
如果是把备份数据还原到其他的gitlab服务器, 那么还原时无需还原key文件

/etc/gitlab/gitlab-secrets.json
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,012评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,628评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,653评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,485评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,574评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,590评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,596评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,340评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,794评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,102评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,276评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,940评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,583评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,201评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,441评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,173评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,136评论 2 352

推荐阅读更多精彩内容