API gateways

Now more and more technical teams are trying to adopt the microservice architecture for product development. However, based on the microservice architecture, the back-end services are usually dynamic. In order to simplify the calling logic of the front-end, API Gateway is usually introduced as a lightweight gateway. At the same time, API Gateway will also implement related authentication logic to simplify internal services. The complexity of calling each other, here we will talk about those things about API Gateway.

"#" Why do you need API Gateway

"#" Simplifies the complexity of client calls

In the microservice architecture mode, the number of instances of backend services is generally dynamic. How can the client find the access address information of these dynamically changed service instances? Therefore, in order to simplify the front-end calling logic in microservice-based projects, API Gateway is usually introduced as a lightweight gateway. At the same time, API Gateway will also implement related authentication logic to simplify the complexity of calling each other between internal services.

http://7pn5d3.com1.z0.glb.clouddn.com/api_gateway.png

"#" Data clipping and aggregation

Generally speaking, different clients have inconsistent data requirements for display, such as mobile phone or web, or in a low-latency network environment or a high-latency network environment.

Therefore, in order to optimize the user experience of the client, API Gateway can tailor the general response data to suit the needs of different clients. At the same time, multiple API call logics can be aggregated to reduce the number of client requests and optimize the client user experience.

"#" Multi-channel support

Of course, we can also provide different API Gateways for different channels and clients. The use of this mode is called Backend for front-end by another well-known way . In the Backend for front-end mode, we can target different Clients create their BFFs individually

backend for front-end

"#" Microservice Transformation of Legacy System

For system systems, microservice transformation is usually due to more or less problems with the original system, such as technical debt, code quality, maintainability, scalability, and so on. The API Gateway model is also suitable for the transformation of this type of legacy system. Through the transformation of microservices, the problems in the original system are gradually repaired, thereby improving the responsiveness of the original business. Gradually replace old implementations with new implementations by introducing layers of abstraction.

"#" Use Zuul to implement API gateway

Spring Cloud's Zuul component provides functional support for lightweight gateways, and a lightweight API gateway can be quickly implemented by defining routing rules

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
zuul:
ignoredPatterns: /api/ auth
sensitive-headers: "*"
ignoreLocalService: true
retryable: false
host:
max-total-connections: 500
routes:
service01:
pateh: /service01/**
serviceId: service01
stripPrefix: true
thirdpart:
pateh: /thirdpart/**
url: http: //thirdpart.api.com

同时除了通过serviceId关联已经注册到Consul的服务实例以外,我们也可以通过zuul直接定义实现对已有服务的直接集成。

这里我们就不过多介绍Zuul的细节,在实际使用中我们会发现直接使用Zuul会存在诸多问题,包括:

  • 性能问题:当存在大量请求超时后会造成Zuul阻塞,目前只能通过横向扩展Zuul实例实现对高并发的支持;
  • WebSocket的支持问题: Zuul中并不直接提供对WebSocket的支持,需要添加额外的过滤器实现对WebSocket的支持;

为了解决以上问题,可以通过在Zuul前端部署Nginx实现对Zuul实例的反向代理,同时适当的通过添加Cache以及请求压缩减少对后端Zuul实例的压力。

"#"实现Nginx的动态代理

通过Nginx我们可以实现对多实例Zuul的请求代理,同时通过添加适当的缓存以及请求压缩配置可以提升前端UI的请求响应时间。这里需要解决的问题是Nginx如何动态发现Zuul实例信息并且将请求转发到Zuul当中。

consul-template可以帮助我们解决以上问题,consul-template是一个命令行工具,结合consul实现配置文件的动态生成并且支持在配置文件发生变化后触发用户自定义命令。

我们使用了如下的Dockerfile用于构建我们的Nginx服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
FROM nginx: 1.11. 10
 
ADD consul-template /usr/local/bin
 
RUN mkdir /etc/consul-templates
 
# 模板文件
ADD nginx.tpl /etc/consul-templates/nginx.tpl
ENV CT_FILE /etc/consul-templates/nginx.tpl
 
ENV NX_FILE /etc/nginx/conf.d/default.conf # 目标文件
 
ENV SERVICE identity # 注册在Consul的服务名
 
COPY dist /usr/share/nginx/html
RUN mkdir -p /data/cache
 
CMD /usr/sbin/nginx -c /etc/nginx/nginx.conf \
& CONSUL_TEMPLATE_LOG=debug \
consul-template -consul-addr= $CONSUL -template "$CT_FILE:$NX_FILE:/usr/sbin/nginx -s reload";

Nginx配置模板文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# nginx.tpl
upstream api_server {
least_conn;
{{range service "identity"}}
server {{.Address}}:{{.Port}};
{{ else}} server 127.0 .0 .1: 9191;{{end}}
}
 
server {
listen 80;
server_name localhost;
 
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
 
location /api {
proxy_pass http: //api_server;
}
}

其中

1
2
3
4
5
6
upstream api_server {
least_conn;
{{range service "identity"}}
server {{.Address}}:{{.Port}};
{{else}}server 127.0. 0. 1: 9191;{{end}}
}

会根据当前consul中注册的所有identity服务实例进行模板渲染,并且当配置文件内容发生变化后调用nginx -s reload重新加载Nginx配置从而实现对于后端服务实例的动态代理。

1
2
3
CMD /usr/sbin/nginx -c /etc/nginx/nginx.conf \
& CONSUL_TEMPLATE_LOG=debug \
consul-template -consul-addr= $CONSUL -template "$CT_FILE:$NX_FILE:/usr/sbin/nginx -s reload";

"#"其它的一些优化建议

启用Nginx的Gzip可以对服务器端响应内容进行压缩从而减少一定的客户端响应时间

1
2
3
4
5
gzip on;
gzip_min_length 1k;
gzip_buffers 4 32k;
gzip_types text/plain application/x-javascript application/javascript text/xml text/css;
gzip_vary on;

缓存图片以及其它静态资源可以减少对Zuul实例的请求量

1
2
3
4
5
6
7
8
9
10
11
12
13
proxy_buffering on;
proxy_cache_valid any 10m;
proxy_cache_path /data/cache levels= 1: 2 keys_zone=my-cache: 8m max_size= 1000m inactive= 600m;
proxy_temp_path /data/temp;
proxy_buffer_size 4k;
proxy_buffers 100 8k;
 
location ~* (images) {
proxy_pass http://api_server;
# cache setting
proxy_cache my-cache;
proxy_cache_valid 200;
}

如果需要通过Nginx实现对Websocket的代理可以添加一下配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
location /sockjs {
proxy_pass http://api_server;
 
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 
# WebSocket support (nginx 1.4)
proxy_http_version 1 . 1 ;
proxy_set_header Upgrade $http_upgrade ;
proxy_set_header Connection "upgrade" ;
proxy_connect_timeout 90 ;
proxy_send_timeout 90 ;
proxy_read_timeout 90 ;
 
# !!!Support Spring Boot
proxy_pass_header X-XSRF-TOKEN;
proxy_set_header Origin "http://localhost:4000" ;
}

 

 

http://yunlzheng.github.io/2017/03/14/the-things-about-api-gateway/

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326595522&siteId=291194637