本文会在腾讯云容器服务上面构造微服务基础小项目, 通过搭建 ELK 集群, 实现利用 Logstash 采集 Nginx 日志, 收纳及利用 kibana 展示的功能, 同时利用 Beego 开发 Rest API, 定义 ELK Service 服务, 实现 ELK Service GET/POST/DELETE/PUT 的功能, 用户可以通过访问 API Gateway 实现对 API 的调用, 获取 CCS 上 ELK 服务的整体功能状态等信息. ELK 服务的所有信息存在于腾讯云 CDB 数据库中, 当服务发生变化, 状态信息会更新数据库, 提供实时信息给用户.
基于腾讯云的这个小项目基本涵盖了微服务基础架构需要的内容, 比如:
a. 选择了 REST, 而不是 RPC
b. 选择腾讯云 CCS 做服务化开发
c. API Gateway 提供 API 鉴权及托管
d. 服务监控可以采用 CCS 提供的服务监控的功能, 也可以搭建 ELK 实现日志收集, 因为 Logstatsh 可以采集 CMQ,
CKafka 等等的日志都可以方便的实现.
e. CCS 提供服务前端的 LB, 支撑外网访问的负载均衡
f. 关于蓝绿部署, 灰度发布, 由于 CCS 容器服务可以非常好的提供 Github CI/CD, 可以非常方便的构建不同版本的
服务, 发布到 API Gateway 提供外网访问, APIGw 可以切换不同的版本环境
如果根据业务需要更加丰富的扩展, 那么腾讯云也提供了非常多的考虑, 比如 TSF 分布式微服务架构, DCDB 分布式数据库, 当然 Redis 等缓存策略也可以在微服务设计上面进行设计构造.
主要的步骤包括:
构造测试 ELK 容器集群, 在腾讯云上分别构建 nginx-basiauth, elasticsearch, logstash, kibana 容器.
在 CVM 安装测试 BeeGO,golong, 调试确认 ELKServiceAPI 功能正常运行
制作 Dockerfile 以及 ENTRYPOINT, 将 ELKServiceAPI commit 到 GitHub, 从 github 构建 ELKServiceAPI 容器镜像
构建 ServiceDiscovery 镜像, 此容器会监控 ELKService 状态, 并写入 ElkserviceAPI 的 CDB 数据库
用户调用 API Gateway, 访问 ELKService 的状态信息
附录参考资料, 代码相关部分可以访问 https://github.com/littleking1/elkserviceapi
首先, 构造测试 ELK 容器集群
总共需要安装四个容器:
a. ElasticSearch 服务: 该服务提供日志集中存储和查询
b. Kibana 服务: 以 web 的形式提供日志的可视化展现和查询界面
c. Kibana 登录鉴权服务: Kibana 如果直接放到公网上, 因为 kibana 本身没有鉴权机制, 如果被端口扫描工具扫出
来, 很容易出现他人查看操作日志的行为, 为避免该 情况, 在 kibana 前面加个 nginx 服务, 利用 nginx 的 basic 认证来做鉴权.
d. nginx 应用服务: 创建该服务的目的是为了验证是否可以将应用日志采集到 ElasticSearch 里. 该服务用 nginx 的访
问日志做日志源, 浏览器每访问一次 nginx 服务, 就会生成一条 access 日志, 和该服务在一起的 logstash 容器会 将
新产生的日志发到 ElasticSearch 里.
首先在容器 CCS 上创建集群, 此集群包括两个集群节点, 后面用来运行多个服务及容器. 由于 ElasticSearch 需要至少 2GB 内存, 我们选择两个节点都配置为 2 核 4GB.
选择机型及主机配置:
在两台主机上分别跑下面的命令:[1]
sysctl -w vm.max_map_count=262144 -- 增大虚拟内存
echo 3> /proc/sys/vm/drop_caches -- 内存不够, 释放部分内存
接下来创建各个服务, 我们选择从 DockerHub 拉取官方镜像:
创建 elasticseach 服务, 该服务包含一个 ES 容器, ES 容器配置硬件:
2. 创建 kibana 服务, 该服务包含一个 kibana 容器, kibana 和 Elasticsearch 之间以服务的方式连接.
3. 创建 nginx 应用服务, 该服务包括两个容器, 一个 nginx 还有一个是 logstash,logstash 和 nginx 容器之间共享数据目录 / var/log/nginx,logstash 采集 nginx 的访问日志文件并将新生成的日志发给 ElasticSearch.
4. 添加 nginx 容器:
当容器服务建立完成后, 访问 nginx 服务 80 端口, 此时会在 nginx 上更新产生的日志信息, 然后打开 kibana, 确认更新的日志信息会完全呈现.
BeeGO API 开发测试
接下来, 在 CVM 安装测试 Beego, 测试基本功能. beego 提供了使用 go 语言进行 Restapi 开发的能力, 同时很好的支持 MVC 模型建立和开发, 实现 ORMapping.
2.1 Ubuntu 16.04 CVM 安装 Golong
添加 apt-get 源并刷新
- $ sudo add-apt-repository ppa:gophers/archive
- $ sudo apt-get update
安装 Go 1.8
$ sudo apt-get install golang-1.8
设置环境变量
等安装完毕后, Go 会被安装到 / usr/lib/go-1.8 目录. 我们要执行 go 命令和建 立自己项目的话, 需要增加一
些环境变量.
代码要放在当前用户下的 Go 目录下, 需要先创建 2 个目录:
- $ mkdir -p ~/go/bin
- $ mkdir -p ~/go/src
然后设置当前用户的环境变量:
vi ~/.profile
在结尾增加以下内容:
- export GOROOT=/usr/lib/go-1.8
- export PATH="$PATH:$GOROOT/bin"
- export GOPATH=$HOME/go
- export PATH="$PATH:$GOPATH/bin"
保存后, 重新刷新环境变量
source ~/.profile
下载需要的 go 项目, 在后面建立 ORMapping 的时候需要使用:
- $ go get -u github.com/astaxie/beego
- $ go get -u github.com/beego/bee
- $ go get github.com/go-sql-driver/mysql
使用腾讯云 CDB , 配置好密码及用户.
登录 mysql, mysql -u root -p XXXX, 创建 elkservice table
- CREATE TABLE `elkservice` (
- `Id` int(11) NOT NULL,
- `Name` varchar(10),
- `Status` varchar(10) ,
- `Running` tinyint(1) ,
- `FailedCount` int(11),
- PRIMARY KEY (`Id`)
- )
定义 ELKService 结构如下:
- type Elkservice struct {
- Id int
- Name string
- Status string
- Running bool
- FailedCount int }
2.2 开发 ELKServiceAPI
创建 API 项目模板 ELKTestAPI
bee api ELKTestAPI
修改项目文件 go/src/ELKTestAPI/models/ELKTestAPI.go, 增加 GET/POST/PUT/DELETE 函数(参考 Github repository)
3. 测试程序可以成功运行:
bee run -gendoc=true -downdoc=true
构造 Dockerfile 及镜像
编写 Dockerfile, 将 ELKService 做成镜像, 上传到腾讯云容器中, 可以参考 Github 上面的 Dockerfile 进行制作 https://github.com/littleking1/elkserviceapi
Dockerfile 中使用下面的 ENTRYPOINT , 在容器开始启动 RestAPI 运行:
- #!/bin/bash
- bee api testuserapi
- cd /root/go/src/ELKTestAPI
- bee run -gendoc=true -downdoc=true
- Github Repository
上传程序源文件到 Github, 在腾讯云容器 CCS 中新建镜像仓库 -- elkapitest
建立镜像构建配置:
Dockerfile 文件在根目录, 所以不需要添加路径, 如果不在根目录, 需要格外添加修改, 例如你的项目名称为 test,Dockerfile 在目录 123/456 下面, 那么 Dockerfile 路径应该填写为 123/456/Dockerfile.
配置完成后, 点击立即构建镜像, 大概需要 5~10 分钟构建:
镜像构建完成后, 在 CCS 上创建服务. 如果定义了触发条件, 每次源码发生变化, 就可以触发服务更新, 使用最新的容器镜像:
查看容器中正在运行的进程, 确认项目已经在运行:
查询 ELKService 的状态, 收到回复如下所示:
构造服务发现镜像
目前 BeeGo Orm 我们采用腾讯云的 CDB 作为 API 数据后端, 用于存储 ELKService 的状态信息. ServiceDiscovery 会监控 ELKService, 主要包括三个容器服务, 当有任何一个服务的状态为不正常的时候, 会发送消息到 CMQ, CMQ 收到当前 ELKService 的状态信息, 触发 SCF 将 ELKService 的状况写入 CDB, 此时开发人员可以通过 ELKService 的 GET 方法获取服务的状态信息. 同时, 在 API 前端使用腾讯云 API Gateway 提供安全防护, 启用 TLS 等安全加密措施.
构造 ServiceDiscovery
构造 SCF 实现读取 CMQ, 并更新 CDB
构造 API Gateway
首先, 下载腾讯云 Python API SDK 到开发环境, https://github.com/QcloudApi/qcloudapi-sdk-python , 由于目前 SDK 中不包含 CMQ, CMQ-Topic 的读写功能, 所以我们需要修改底层的 module, 实现 CMQ 的 API 调用功能.
- $ git clone https://github.com/QcloudApi/qcloudapi-sdk-python
- $ cd qcloudapi-sdk-python
进入 module 目录, 新建文件 cmq.py , 并贴入下面的内容:
- from QcloudApi.modules import base
- class Cmq(base.Base):
- requestHost = 'cmq-queue-sh.api.qcloud.com'
- ~
回到 QcloudApi 目录, 打开 qcloudapi.py, 添加 cmq 信息:
修改完成保存后, 运行命令安装 SDK:
python setup.py install
进入 tests 目录, 打开 demo.py, 并编写 ServiceDiscovery 程序, 具体参考 https://github.com/littleking1/elkserviceapi/tree/master/ServiceDis/tests
接下里构造 SCF, 实现读取 CMQ Topic, 并将信息写入到 CDB, 参考 https://github.com/littleking1/elkserviceapi/tree/master/SCF
创建 CMQ Topic 触发, 确定消息可以成功触发 SCF, 并成功写入 CDB.
构造 API Gateway
接下来, 我们可以在 API 前端构造 API Gateway, 来实现对 API 的托管功能了.
API 网关是用于实现完整 API 托管的服务, 用于协助开发者轻松完成 API 的创建, 维护, 发布, 监控等整个生命周期的管理. 通过 API 网关, 可以封装后端各种服务, 以 API 的形式, 提供给各方使用. 同时, API 网关可以协助完成 API 文档管理, API 测试和 SDK 生成等.
同时, 由于 API Gateway 利用 TGW(Tencent Gateway) 的强大能力, 依赖其多地域多机分布式集群, 提供高性能高可靠的服务, 用于承载大规模大流量的 API 访问. 同时利用腾讯云 API key 的 secretid, secretkey 提供非常安全的 API 鉴权功能, 保证 API 不会被非法使用.
在 API Gateway 创建服务测试:
配置后端路径:
设置返回类型为 Json:
调试 API, 确认可以返回结果:
服务测试
手动将 ELK 其中一项服务 (例如 elasticsearch) 关停, 或者扩容实例, 此时服务会从 normal 状态变换到其他状态:
service Discovery 将服务信息写入 CMQ, SCF 被调用:
通过 postman 查看 API Gateway, 调用 ELKService 接口, 可以查到 elkservice 的状态已经发生变化:
[附录]
- [1] https://cloud.tencent.com/developer/article/1005427
- [2] https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/05.5.md
- [3] https://docs.docker.com/engine/reference/builder/#entrypoint
- [4] http://www.linuxidc.com/Linux/2018-01/150348.htm
- [5] https://www.gfzj.us/2015/07/07/dockerfile_set_PATH.html
- [6] https://yeasy.gitbooks.io/docker_practice/content/basic_concept/image.html
- [7] https://cloud.tencent.com/document/product/457/9115
- [8] https://cloud.tencent.com/document/product/583/9734
- [9] https://github.com/littleking1/elkserviceapi
来源: https://cloud.tencent.com/developer/article/1078010?fromSource=waitui