1. 需求分析
无论是单体应用,SOA和微服务框架下,网关的存在是很必要。网关作为一个内网开发的入口。一些公共服务的建设,可以在网关层处理。
我们的网关需要满足的功能:
- 路由转发
- 请求鉴权和身份认证
- 限流
- 跨域
- 流量监控
- 请求日志
- ACL控制
2. 需求设计
[图片上传失败...(image-6d9ec1-1525610508767)]3. 实现demo
3.1. 第一版本
第一版本,使用nodejs代码自研实现,满足跨域请求,路由转发和请求鉴权,其他功能未完成。
实现思路:代码层实现路由的转发,通过消息的解析再封装实现,鉴权使用jwt实现。自研的确定是所有的需求都需要开发,目前阶段不能快速完成迭代,响应需求慢。
3.2. 第二版本
选择开源组件kong作为前后端的网关
3.2.1. 安装
使用docker安装
-
安装数据库
sudo docker run -d --name kong-database \ -p 5432:5432 \ -e "POSTGRES_USER=kong" \ -e "POSTGRES_DB=kong" \ postgres:9.5
-
迁移数据
sudo docker run --rm \ --link kong-database:kong-database \ -e "KONG_DATABASE=postgres" \ -e "KONG_PG_HOST=kong-database" \ -e "KONG_CASSANDRA_CONTACT_POINTS=kong- database" \ kong:latest kong migrations up
-
启动kong(限制只有本机访问)
sudo docker run -d --name kong \ --link kong-database:kong-database \ -e "KONG_DATABASE=postgres" \ -e "KONG_PG_HOST=kong-database" \ -e "KONG_CASSANDRA_CONTACT_POINTS=kong- database" \ -e "KONG_PROXY_ACCESS_LOG=/dev/stdout" \ -e "KONG_ADMIN_ACCESS_LOG=/dev/stdout" \ -e "KONG_PROXY_ERROR_LOG=/dev/stderr" \ -e "KONG_ADMIN_ERROR_LOG=/dev/stderr" \ -e "KONG_ADMIN_LISTEN=0.0.0.0:8001" \ -e "KONG_ADMIN_LISTEN_SSL=0.0.0.0:8444" \ -p 8000:8000 \ -p 8443:8443 \ -p 127.0.0.1:8001:8001 \ -p 127.0.0.1:8444:8444 \ kong:latest
-
安装dashboard
sudo docker run -d -p 8080:8080 pgbi/kong-dashboard:v2
3.2.2. 使用
-
新增api(hosts选填)
curl -i -X POST --url http://127.0.0.1:8001/apis/ --data 'name=test' --data 'upstream_url=http://112.74.29.177:8080/WeChat_Services/project/getProject' --data 'uris=/getuserinfo,/getnatipmapinfo,/getimeibindinfo' --data 'strip_uri=true' --data 'hosts=order.geneseeq.com'
说明:strip_uri为false,表示uris要追加到upstream_url上;如果strip_uri为true,表示uris追加到ip下
测试是否添加转发url成功 执行: curl -i -X GET --url http://localhost:8000/getuserinfo
-
新增jw功能
(1)新增jwt插件
curl -X POST http://127.0.0.1:8001/apis/test/plugins \ --data "name=jwt"
(2)创建消费者
curl -X POST http://127.0.0.1:8001/consumers \ --data "username=test" \ --data "custom_id=test"
(3)给消费者创建jwt
curl -X POST http://127.0.0.1:8001/consumers/test/jwt -H "Content-Type: application/x-www-form-urlencoded"
(4)查看创建jwt
curl -X GET http://127.0.0.1:8001/consumers/test/jwt
(5)测试携带token访问
curl -i -X GET --url http://localhost:8000/getuserinfo -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJSSGY5RkFldVFrbnVaNERGcXk2enI0bnViMXVtV3NrWSIsIm5hbWUiOiJKb2huIERvZSIsImlhdCI6MTUxNjIzOTAyMn0.7pQIClh6XCP3XFWTsK2B4DnbajyYblPfh7rPQPSVMro' 或者 curl -i -X GET --url http://localhost:8000/getuserinfo?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJSSGY5RkFldVFrbnVaNERGcXk2enI0bnViMXVtV3NrWSIsIm5hbWUiOiJKb2huIERvZSIsImlhdCI6MTUxNjIzOTAyMn0.7pQIClh6XCP3XFWTsK2B4DnbajyYblPfh7rPQPSVMro
-
设置dashborad访问权限
(1)建立admin的lookback
curl http://localhost:8001/apis \ --data name=admin-api \ --data uris=/admin-api \ --data upstream_url=http://localhost:8001
(2)新增basic-auth插件
curl -X POST http://127.0.0.1:8001/apis/admin-api/plugins \ --data "name=basic-auth" \ --data "config.hide_credentials=true"
(3)创建消费者
curl -d "username=user123&custom_id=SOME_CUSTOM_ID" http://127.0.0.1:8001/consumers/
(4)新增认证的账号和密码
curl -X POST http://127.0.0.1:8001/consumers/user123/basic-auth \ --data "username=admin" \ --data "password=geneseeq"
(5)打开dashboard:http://192.168.17.175:8080
[图片上传失败...(image-43c527-1525610508767)]
-
删除命令
(1)删除api
curl -X DELETE http://127.0.0.1:8001/apis/kong_dashboard4
(2)删除消费者
curl -X DELETE http://127.0.0.1:8001/consumers/user123
(3)删除插件
curl -X DELETE http://127.0.0.1:8001/apis/kong_dashboard4/plugins3.2.3. 多服务版本分流(适用于金丝雀发布)
3.2.3. 多服务版本分流(适用于金丝雀发布)
-
创建upstream
curl -H "Content-Type: application/json" -X POST -d '{"name":"hello"}' http://127.0.0.1:8001/upstreams/
-
指定upstream的targets和权重
curl -H "Content-Type: application/json" -X POST -d '{"target": "192.168.17.172:8082", "weight": 100 }' http://127.0.0.1:8001/upstreams/hello/targets curl -H "Content-Type: application/json" -X POST -d '{"target": "192.168.17.172:8083", "weight": 100 }' http://127.0.0.1:8001/upstreams/hello/targets
-
新增api
curl -H "Content-Type: application/json" -X POST -d '{"name":"hello","upstream_url":"http://hello","strip_uri":true, "uris":"/api/v1.0"}' http://127.0.0.1:8001/apis/
3.3. 第三版本
使用spring cloud实现gateway,鉴于现有开发人员技能,建议使用Kong+spring cloud实现网关,包括自定义过滤等功能。
3.3.1. 注册中心
spring cloud的网关需要配合注册中心使用,网关自动发现服务,这里介绍两个网关:consul和eureka,建议使用consul,支持跨语言
3.3..1.1. Eureka
注册中心需要有服务端和客户端,eureka注册中心使用spring boot代码开发启动即可
-
Eureka服务端
(1)引入服务端jar包
[图片上传失败...(image-236b72-1525610508767)]
(2)新增配置
[图片上传失败...(image-4736ac-1525610508767)]
(3)启动程序启用eureka服务端注解
[图片上传失败...(image-3260f0-1525610508767)]
(4)构建完启动程序后,可以访问http://localhost:1001/查看注册的服务
[图片上传失败...(image-be1939-1525610508767)]
-
微服务注册
(1)引入客户端jar包
[图片上传失败...(image-ad59a4-1525610508767)]
(2)新增配置
[图片上传失败...(image-ed940b-1525610508767)]
(3)启动程序启用eureka客户端注解
[图片上传失败...(image-433537-1525610508767)]
(4) 构建完成启动后,会发现服务注册到eureka服务端
[图片上传失败...(image-890f10-1525610508767)]
3.3.1.2. consul
-
consul服务端
(1)安装服务端
我们使用docker方式安装consulserver: https://hub.docker.com/r/progrium/consul/
执行命令:sudo docker run -p8400:8400 -p 8500:8500 -p 8600:53/udp -h node1 progrium/consul -server-bootstrap -ui-dir /ui
(2)访问http://192.168.17.175:8500/ui
[图片上传失败...(image-5eb980-1525610508767)]
-
微服务注册
(1)引入客户端jar包
[图片上传失败...(image-d8e88-1525610508767)]
(2)新增配置
[图片上传失败...(image-aec453-1525610508767)]
(3)启动程序启用consul客户端注解
[图片上传失败...(image-b01dd6-1525610508767)]
(4)构建完成启动后,会发现服务注册到consul服务端,访问: http://192.168.17.175:8500/ui
[图片上传失败...(image-9600af-1525610508767)]
3.3.2. 网关
3.3.2.1. Eureka实现gateway
网关也需要注册到eureka服务端,来发现服务。网关使用spring zuul实现,屏蔽eureka和consul底层,属于通用用法
- 引入客户端jar包和zuul jar包
[图片上传失败...(image-2943fc-1525610508767)]
- 新增配置
[图片上传失败...(image-f2b459-1525610508767)]
- 启动程序中引入注解
[图片上传失败...(image-e50653-1525610508767)]
- 构建完成后,启动网关
- 测试
访问127.0.0.1:8888/eureka-client/test/greeting
[图片上传失败...(image-6cac4-1525610508767)]
3.3.2.2. consul实现gateway
- 引入consul客户端jar包和zuul jar包
[图片上传失败...(image-3c617d-1525610508767)]
- 新增配置
[图片上传失败...(image-87857c-1525610508767)]
- 启动程序中引入注解
[图片上传失败...(image-9bbbed-1525610508767)]
- 构建完成,启动网关
- 测试
访问http://127.0.0.1:8888/test/greeting
[图片上传失败...(image-e383b8-1525610508767)]