Fizz 网关简介
Fizz Gateway 是一个基于 Java开发的微服务网关,能够实现热服务编排、自动授权选择、线上服务脚本编码、在线测试、高性能路由、API审核管理等目的,拥有强大的自定义插件系统可以自行扩展,并且提供友好的图形化配置界面,能够快速帮助企业进行API服务治理、减少中间层胶水代码以及降低编码投入、提高 API 服务的稳定性和安全性。
整体架构
Fizz网关的核心处理流程如上图, 收到客户端的请求后会经过一系列内置或自定义的过滤器,接着网关会自动判断当前请求的接口是否是服务编排接口,如果是服务编排接口就根据配置文件创建一个pipeline,在服务编排的pipeline里可以实现接口的串联或并联调用,可以对输入和输出的内容做数据转换,字段映射,脚本处理等操作;如果不是服务编排接口则直接反向代理到后端服务,最后把响应结果返回给客户端。
主要功能特性
- 集群管理:Fizz网关节点是无状态的,配置信息自动同步,支持节点水平拓展和多集群部署。
- 服务编排:支持热服务编排能力,支持前后端编码,随时随地更新API。
- 负载均衡:支持round-robin负载均衡。
- 服务发现:支持从Eureka注册中心发现后端服务器。
- 配置中心:支持接入apollo配置中心。
- HTTP反向代理:隐藏真实后端服务,支持 Rest API反向代理。
- 访问策略:支持不同策略访问不同的API、配置不同的鉴权等。
- IP黑白名单:支持配置IP黑白名单。
- 自定义插件:强大的插件机制支持自由扩展。
- 可扩展:简单易用的插件机制方便扩展功能。
- 高性能:性能在众多网关之中表现优异。
- 版本控制:支持操作的发布和多次回滚。
- 管理后台:通过管理后台界面对网关集群进行各项配置。
Fizz网关支持以上功能特性,跟其它网关不同的是,Fizz更加关注是的API的管理、二次开发和开发速度的提升,所以提供强大的插件机制支持自由扩展,提供热服务编排能力,通过服务编排可以通过在线配置的方式快速生成一个新的接口。
安装使用
安装依赖
安装以下依赖软件:
- Redis 2.8或以上版本
- MySQL 5.7或以上版本
- Apollo配置中心 (可选)
- Eureka服务注册中心
安装MySQL
- 操作系统 CentOS 6.5
- MySQL 5.7.30
- 下载MySQL
wget https://downloads.mysql.com/archives/get/p/23/file/mysql-5.7.30-1.el6.x86_64.rpm-bundle.tar
- 解压
tar -xvf mysql-5.7.30-1.el6.x86_64.rpm-bundle.tar
- 安装
sudo yum install mysql-community-{server,client,common,libs}-*
- 启动
sudo service mysqld start
启动成功会显示以下信息:
[root@localhost ~]# sudo service mysqld start
Initializing MySQL database: [ OK ]
Starting mysqld: [ OK ]
- 初始密码
sudo grep 'temporary password' /var/log/mysqld.log
- 使用初始密码登录
mysql -uroot -p
- 修改密码
ALTER USER 'root'@'localhost' IDENTIFIED BY 'MyNewPass4!';
- 退出登录
quit
安装Redis 6.0.8
- 下载解压并编译
$ wget http://download.redis.io/releases/redis-6.0.8.tar.gz
$ tar xzf redis-6.0.8.tar.gz
$ cd redis-6.0.8
$ make
- 启动redis
运行编译后的文件:
$ src/redis-server
- 客户端连接
$ src/redis-cli
redis> set foo bar
OK
redis> get foo
"bar"
安装Apollo配置中心
说明: apollo是可选组件,如果不使用apollo可使用本地配置文件(application.yml), 如果不使用apollo可跳过此步骤。
安装步骤详见apollo官方文档:
安装Eureka服务注册中心
环境要求:
- JDK 1.8 或以上版本
- Tomcat 6.0.10 或以上版本 (如使用spring cloud已内置)
- 安装JDK 1.8
1)下载JDK,如: jdk-8u192-linux-x64.tar.gz
tar -zxvf jdk-8u192-linux-x64.tar.gz
mv jdk1.8.0_192 /usr/local/
2)设置JDK环境变量,将下面内容追回到/etc/profile文件后面
JAVA_HOME=/usr/local/jdk/jdk1.8.0_192
JRE_HOME=$JAVA_HOME/jre
PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin
CLASSPATH=:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib/dt.jar
export JAVA_HOME JRE_HOME PATH CLASSPATH
3)执行以下命令全环境变量生效:
source /etc/profile
4)查看是否安装成功
java -version
- 安装eureka
1)使用IDE创建一个spring boot项目,如:sc-eureka-server
pom.xml:
org.springframework.cloud
spring-cloud-starter-netflix-eureka-server
在启动类上添加@EnableEurekaServer注解来启用Euerka注册中心功能:
@SpringBootApplication
@EnableEurekaServer
public class ScEurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(ScEurekaServerApplication.class, args);
}
}
application.properties配置文件:
spring.application.name=sc-eureka-server
server.port=8761
eureka.instance.hostname=localhost
eureka.client.registerWithEureka=false
eureka.client.fetchRegistry=false
eureka.server.enableSelfPreservation=false
2) maven构建并运行sc-eureka-server应用, 启动后访问地址http://localhost:8761/可以看到Eureka注册中心的界面
3)把target/sc-eureka-server-1.0.0.jar传到linux服务器上运行. (仅以单机部署为例)
nohub java -jar sc-eureka-server-1.0.0.jar &
4)eureka客户端的注册地址为:http://localhost:8761/eureka/ (替换localhost为服务器的IP)
eureka.client.serviceUrl.defaultZone = http://localhost:8761/eureka/
安装Fizz
管理后台
从github的releases(https://github.com/wehotel/fizz-gateway-community/releases)下载 fizz-manager-professional 和 fizz-admin-professional 的安装包
- 管理后台服务端(fizz-manager-professional)
- 首次安装执行
fizz-manager-professional-1.0.0-mysql.sql
数据库脚本 - 将
application-prod.yml
、boot.sh
、fizz-manager-professional-1.0.0.jar
拷贝到/data/webapps/fizz-manager-professional
目录下 - 修改
application-prod.yml
文件,将相关配置修改成部署环境的配置 - 修改
boot.sh
文件,将RUN_CMD
变量值修改成部署环境的JAVA实际路径 - 执行
chmod +x boot.sh
命令给boot.sh
增加执行权限 - 执行
./boot.sh start
命令启动服务,支持 start/stop/restart/status命令 - 服务启动后访问 http://IP:8000/fizz-manager (将IP替换成服务部署机器IP地址),使用超级管理员账户
admin
密码Aa123!
登录
- 管理后台前端(fizz-admin-professional)
zip资源包解压后,取文件夹【fizzAdmin】放置于服务器静态数据存放目录 如:/home/data/
nginx配置
server {
listen 9000;
server_name localhost:9000;
location / {
root /home/data/fizzAdmin;
}
location ^~ /api {
rewrite ^/api/(.*) /$1 break;
proxy_pass http://127.0.0.1:8000;
}
}
# 注:root中地址需与资源包存放目录路径一致
# 注:http://127.0.0.1:8000 为管理后台(fizz-manager-professional)的访问地址
访问地址
【资源部署服务器IP + 端口号】如:http://127.0.0.1:9000/
(端口号与nginx配置端口号一致)
fizz-gateway-community社区版
说明:如果使用apollo配置中心,可把application.yml文件内容迁到配置中心(apollo上应用名为:fizz-gateway);使用不使用apollo可去掉下面启动命令里的apollo参数。
脚本启动:
- 下载fizz-gateway-community的最新代码,修改application.yml配置文件里eureka、redis的配置,使用maven构建好并把构建好的fizz-gateway-community-1.0.0.jar和boot.sh放同一目录
- 修改boot.sh脚本的apollo连接,JVM内存配置,
- 执行
./boot.sh start
命令启动服务,支持 start/stop/restart/status命令
IDE启动:
- 本地clone仓库上的最新代码
- 将项目fizz-gateway导入IDE
- 导入完成后设置项目启动配置及修改application.yml配置文件里eureka、redis的配置,在VM选项中加入
-Denv=dev -Dapollo.meta=http://localhost:66
(Apollo配置中心地址)
jar启动:
- 本地clone仓库上的最新代码,修改application.yml配置文件里eureka、redis的配置
- 在项目根目录fizz-gateway-community下执行Maven命令
mvn clean package -DskipTests=true
打包 - 进入target目录,使用命令
java -jar -Denv=DEV -Dapollo.meta=http://localhost:66 fizz-gateway-community-1.0.0.jar
启动服务
网关访问地址格式:
http://127.0.0.1:8600/proxy/[服务名]/[API Path]
服务编排
服务编排配置例子
假如我们已经有积分和优惠券两个内部公共的微服务,现在我们要开发一个会员资产信息接口返回积分数和优惠券张数(积分服务和优惠券服务已分别有查询积分数和券数量的接口),下面我们通过服务编排的方式实现这个会员资产接口
已有的积分和优惠券接口:
- 查询会员积分接口
- 接口URL:http://points-service/points/getMebPoints
- 请求方法:GET
- 入参: 会员ID(memberId)
- 返回结果:{"code": 0, "msg": "ok", "data": {"points":12000}}
- 查询会员优惠券数量接口
- 接口URL:http://coupon-service/coupon/getCouponCount
- 请求方法:GET
- 入参: 会员ID(memberId)
- 返回结果:{"code": 0, "msg": "ok", "data": {"count":3}}
我们要配置的会员资产信息接口:
接口URL:http://member-assets/assets/getAssetsInfo
请求方法:GET
入参: 会员ID(memberId)
返回结果:{"code": 0, "msg": "ok", "data": {"points": 12000, "coupons":3}}
新增一个服务
登录管理后台,打开服务编排->服务管理菜单,点击新增按钮新建一个服务:member-assets,这个服务可以理解为我们平时的微服务。建好服务后就可以在这个服务下创建服务编排接口啦
新增服务编排接口
配置基础信息
打开服务编排->接口列表菜单,点击新增新建一个接口,在新增页面里选择服务 member-assets, 填写接口名称,URL等必填信息
- 接口名称:会员资产信息
- 方法:GET
- 路径:/assets/getAssetsInfo
配置输入
会员资产信息接口只需要一个会员ID的参数,我们只需配置一个Query参数
{
"type": "object",
"properties": {
"memberId": {
"type": "integer",
"title": "会员ID"
}
},
"required": [
"memberId"
]
}
配置步骤
因为积分和优惠券之间没有依赖关系,可以并发请求。只需配置一个step并发调用这两个接口,每调用一个接口对应一个request
配置request1来调用会员积分接口
请求方法:选GET
默认URL:http://points-service/points/getMebPoints (因为服务已注册到eureka通过服务名调用即可,各个环境的URL都一样,只需配置默认URL,各个环境的URL留空)
-
配置入参:因为是GET请求只需配置Query参数,会员积分接口的入参(会员ID)要引用会员资产信息接口的入参(会员ID),可以通过引用值来实现
- 字段(即会员积分接口入参名):memberId
- 类型:选择引用值
- 数据类型:number, 因为会员资产信息接口和会员积分接口的入参都是memberId而且都是int类型,所以也可以不指定。如果会员资产信息接口的memberId是字段串类型,则须选number,这样系统会自动做类型强转
- 值:input.request.params.memberId (填写引用的路径即可,路径规范可点问号icon查看或查看官方使用文档)
配置响应:因为接口返回的结果简单不需要做字段映射或数据转换,所以不配置。
配置request2来调用会员优惠券数量接口
- 请求方法:选GET
- 默认URL:http://coupon-service/coupon/getCouponCount (因为服务已注册到eureka通过服务名调用即可,各个环境的URL都一样,只需配置默认URL,各个环境的URL留空)
- 配置入参:因为是GET请求只需配置Query参数,会员优惠券数量接口的入参(会员ID)要引用会员资产信息接口的入参(会员ID),可以通过引用值来实现
- 字段(即会员积分接口入参名):memberId
- 类型:选择引用值
- 数据类型:number, 因为会员资产信息接口和会员优惠券数量接口的入参都是memberId而且都是int类型,所以也可以不指定。如果会员资产信息接口的memberId是字段串类型,则须选number,这样系统会自动做类型强转
- 值:input.request.params.memberId (填写引用的路径即可,路径规范可点问号icon查看或查看官方使用文档)
- 配置响应:因为接口返回的结果简单不需要做字段映射或数据转换,所以不配置。
配置步骤结果留空即可,对于有多步骤的复杂接口
配置输出
输出指的是会员资产信息接口的响应,我们要配置以下格式的响应报文
{
"code": 0,
"msg": "ok",
"data": {
"points": 12000,
"coupons": 3
}
}
- 配置小知识
- 响应体和请求体的字段支持多级的写法,如: data.points
- 字段映射,如:data.coupons 取的是step1里request2的响应body里的data.count的值,这样配置就自动完成了coupons到count的字段映射
- 当类型为固定值时数据类型为必填,因为要明确告诉程序后面填写的值是什么类型
配置路由
会员资产信息接口配置好后,还需要配置路由才能通过网关来访问(前提:配置好的接口需要发布到网关,目前会员资产信息接口仍是未发布状态),路由不仅可以用来反向代理服务编排的接口,也可以反向代理其它微服务的接口,更多路由的功能可参考官方文档。
配置步骤说明:
- 在路由管理里新增路由
- 网关分组:选择默认分组 (一个大网关集群可以根据需要分成不同分组,一般情况下只用默认分组就足够了,关于分组的用法可查看官方使用文档)
- 服务:填写服务名 member-assets
- 访问:允许
- 其它可选项不配置,这样整个服务都允许通过网关来访问了。也可以根据需要按接口路径来配置只暴露部分接口,同时也可指定此路由只能由指定的应用(调用方appid)来访问
- 插件:可以为路由添加各种插件,如:会员登录态校验等。此例子只做简单的演示就不配置了
测试
接口配置好后可以在发布前通过测试功能来验收是否正确, 点击编辑接口,在编辑页面的右上角点击测试按钮进到测试页面,一个类似postman的测试工具,填写参数进行测试
发布
Fizz提供了一套发布申请审核流程来保证接口的安全,只把权限分配给有需要的人员。在开发环境为了方便我使用超级管理员账号进行发布申请和审核。步骤如下:
- 在发布申请-我的申请页面或服务编排的接口列表页面,点击"发布|下线申请"
- 添加要发布的接口,选择会员资产信息接口
- 填写标题、类型和申请原因等
- 选择审核人选择超级管理员,提交申请
- 在待审核列表里审核上一次提交的申请单
- 审核通过后在我的申请页面查看申请单详情,点击发布即可
- 发布后可以通过网关来访问接口,如: http://127.0.0.1:8600/proxy/member-assets/assets/getAssetsInfo?memberId={填写会员ID}
结束
通过一个简单的例子体验了Fizz网关的服务编排和路由功能,服务编排功能可以取代很多数据聚合类型的接口,这类型接口的业务逻辑少一般只按需聚合页面所需的数据和做简单的数据转换,通过可视化界面简单配置一下即可完成以前要花一两天才能开发完的接口,节省了开发时间和机器成本。