1. Gateway service
1. Gateway mode
As the outermost service of the architecture, the gateway is used to uniformly intercept requests from various ports, identify the validity of requests, intercept abnormal actions, and provide routing and load capabilities to protect business services; this strategy is similar to the appearance mode.
The gateway service and the facade service have some similar logic. The interception of the gateway service focuses on processing common policies and routing loads, while the different facade aggregation services focus on scene classification, such as several common facade services:
- Facade : Port requests opened by service products, such as Web, App, applet, etc.;
- Admin : Usually serves internal management systems, such as Crm, BI reports, consoles, etc.;
- Third : Aggregate third-party docking services, such as SMS, risk control, action tracking, etc.;
Different facade services also have specific interception strategies. If the Facade, Admin, Third and other verifications are integrated in the gateway, it will obviously increase the burden of the gateway service, which is not conducive to the stability of the architecture.
2. Gateway component
If the microservice architecture was exposed earlier, the Zuul component was often used in the initial gateway, and the Gateway component was released by SpringCloud later, which is a common selection at present.
- Request interception: The gateway acts as an open entry for API requests, and it is the basic ability to complete request interception, identification and verification;
- Custom strategy: In addition to routine identification, design corresponding interception logic according to service scenarios, and try to intercept abnormal requests;
- Service routing: The request is forwarded to a specific business service after interception. There are two core action routes and loads;
As a commonly used selection component in the microservice architecture, the following is a detailed analysis of the usage of the Gateway gateway, the docking process and mode with other components from the usage details.
As the registration and configuration center of microservices, Nacos is already a commonly used component, and Nacos also provides an integration case of Gateway components. The first is to register the gateway service to Nacos:
spring:
cloud:
nacos:
config:
server-addr: 127.0.0.1:8848
discovery:
server-addr: 127.0.0.1:8848
Nacos manages gateway service registration and related configuration files. In projects, it usually shares a set of MySQL libraries with nacos to manage the service routing data of the gateway. It is a relatively common solution today.
3. Gateway interception
GlobalFilter : The global filter in the gateway, intercepts all requests passing through the gateway, and determines whether the request needs to be executed after the corresponding verification strategy:
@Order(-1)
@Component
public class GatewayFilter implements GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
return chain.filter(exchange);
}
}
Usually, some necessary common interception is performed in the gateway, such as: IP black and white list, Token identity token, obtain the corresponding parameters in the request, and execute the verification method of related services.
4. Dynamic routing
4.1 Route Definition
In the implementation of service routing, there are complex logic and strategies to adapt to various scenarios; how to define the concept of routing, you can refer to the source code RouteDefinition
object of the Gateway component, the structure involves several core attributes: routing, assertion, filtering , metadata:
- Route: consists of ID, forwarding Uri, assertion, filtering, and metadata;
- Predicate assertion: Determine whether the request matches the route;
- Filter: You can modify the request action, such as parameters;
- Metadata metadata: load the metadata of the routing service;
@Validated
public class RouteDefinition {
private String id;
@NotNull
private URI uri;
@NotEmpty
@Valid
private List<PredicateDefinition> predicates = new ArrayList<>();
@Valid
private List<FilterDefinition> filters = new ArrayList<>();
private Map<String, Object> metadata = new HashMap<>();
}
These routes are usually placed in the config_route data table of the nacos library, and the corresponding table data can be managed around the structure of the above routing objects:
There are also different configurations for the forwarding target uri. Here, the mode of lb://service registration name is selected, that is, the request load is distributed to the service node corresponding to the route, and the Ribbon load algorithm is used inside the Nacos component. You can refer to related 's documentation.
4.2 Admin Routing
There are two core interfaces for routing management: Locator loading and
Writer additions and deletions, and also provides an aggregated
Repository
interface:
public interface RouteDefinitionLocator {
// 获取路由列表
Flux<RouteDefinition> getRouteDefinitions();
}
public interface RouteDefinitionWriter {
// 保存路由
Mono<Void> save(Mono<RouteDefinition> route);
// 删除路由
Mono<Void> delete(Mono<String> routeId);
}
public interface RouteDefinitionRepository extends RouteDefinitionLocator, RouteDefinitionWriter{}
In this way, by defining the routing management component, the above-mentioned aggregation interface is implemented, and the process of loading routing data from the data table to the application is completed:
@Component
public class RouteFactory implements RouteDefinitionRepository {
@Resource
private RouteService routeService ;
// 加载全部路由
@Override
public Flux<RouteDefinition> getRouteDefinitions() {
return Flux.fromIterable(routeService.getRouteDefinitions());
}
}
RouteService is a service class for route management, which manages configuration data and the conversion of entity objects and route definition objects:
@Service
public class RouteServiceImpl implements RouteService {
// 数据库路由实体,转换为网关路由的定义对象
private RouteDefinition buildRoute (ConfigRoute configRoute){
RouteDefinition routeDefinition = new RouteDefinition () ;
// 基础
routeDefinition.setId(configRoute.getRouteId());
routeDefinition.setOrder(configRoute.getOrders());
routeDefinition.setUri(URI.create(configRoute.getUri()));
// 断言
routeDefinition.setPredicates(JSONUtil.parseArray(configRoute.getPredicates()).toList(PredicateDefinition.class));
// 过滤
routeDefinition.setFilters(JSONUtil.parseArray(configRoute.getFilters()).toList(FilterDefinition.class));
return routeDefinition ;
}
}
Through the above process, the routing information can be persistently stored in the database. If there are few service nodes, it can also be managed directly in the nacos configuration file.
4.3 Match pattern
Predicate assertion is actually the setting of a matching rule. Looking at the relevant source code of PredicateDefinition
, we can see that there are various modes such as Host, Path, Time, etc. From the above data, we can see that the path matching is used in this article.
Since the path matching method is used, / service name will be spliced at the starting position of the uri, so when configuring the filtering rules, set StripPrefix to remove the routing identifier.
After the request enters the gateway, it first enters the global interceptor to execute the verification strategy. After the verification is passed, the service that matches the relevant route is filtered. After the match is successful, the filtering operation is performed, and finally the request is forwarded to the corresponding service. This is the core of the request to be executed in the gateway. process.
2. Registration and configuration
Nacos provides two core capabilities of service registration and configuration management in the entire microservice system. Usually, only the core bootstrap
configuration file is reserved in the code project, which can greatly simplify the configuration in the project and improve the security of related data.
1. Service registration
Nacos supports DNS-based and RPC-based service discovery, and provides real-time health checks for services, preventing requests to unhealthy hosts or service instances:
In the registration list of the service, you can view the registration information, the number of healthy instances, etc., and you can delete the registered service; you can view the specific instance information in the details, and you can dynamically log on and off the service instance and edit related configurations.
2. Configuration file
Usually, the management of the namespace
namespace is used to isolate the registration and configuration of different services, which can be viewed in the nacos library tenant_info
. Generally, there are the following categories:
This is the most common namespace. The gateway gateway is relatively independent, and the configuration of the seate transaction is relatively complex. The serve business service has a large number of public configurations, and the following strategies are usually adopted:
- application.yml : common configuration for all services, such as mybatis;
- dev||pro.yml : Environment isolation configuration, different middleware addresses are set for different environments;
- serve.yml : Personalized configuration of the service, such as connected libraries, parameters, etc.;
spring:
application:
name: facade
profiles:
active: dev,facade
cloud:
nacos:
config:
prefix: application
file-extension: yml
server-addr: 127.0.0.1:8848
discovery:
server-addr: 127.0.0.1:8848
The service will identify and load the corresponding configuration file through the above profiles
parameters. In this management mode, the differences in the environment can only be maintained in the dev||pro.yml
configuration file, and other configurations will be relatively stable.
3. Calling between services
1. Feign components
The Feign component is a declarative and templated HTTP client, which can make the calls between services simpler and more elegant. Usually, the Feign interface provided by the service is managed in a separate code package, which is convenient for other services to rely on and use:
/**
* 指定服务名称
*/
@FeignClient(name = "account")
@Component
public interface FeignService {
/**
* 服务的API接口
*/
@RequestMapping(value = "/user/profile/{paramId}", method = RequestMethod.GET)
Rep<Entity> getById(@PathVariable("paramId") String paramId);
}
public class Rep<T> {
// 响应编码
private int code;
// 语义描述
private String msg;
// 返回数据
private T data;
}
Usually, the response format of the Feign interface is packaged to realize the unified management of the return parameter structure, which is conducive to the identification of the calling end. Here, it involves the processing of generic data.
2. Response decoding
By inheriting the ResponseEntityDecoder
class, implement custom Feign interface response data processing, such as return parameter style, data conversion, etc.:
/**
* 配置解码
*/
@Configuration
public class FeignConfig {
@Bean
@Primary
public Decoder feignDecoder(ObjectFactory<HttpMessageConverters> feignHttpConverter) {
return new OptionalDecoder(
new FeignDecode(new SpringDecoder(feignHttpConverter)));
}
}
/**
* 定义解码
*/
public class FeignDecode extends ResponseEntityDecoder {
public FeignDecode(Decoder decoder) {
super(decoder);
}
@Override
public Object decode(Response response, Type type) {
if (!type.getTypeName().startsWith(Rep.class.getName())) {
throw new RuntimeException("响应格式异常");
}
try {
return super.decode(response, type);
} catch (IOException e) {
throw new RuntimeException(e.getMessage());
}
}
}
3. Request parsing
The communication request between services can be easily realized by using the annotation method. You can understand the encapsulation logic by referring to the source code of the Feign component, which is to convert the interface call into an HTTP request:
- FeignClientBuilder : Directly build the client of Feign requests without using annotations. This class helps to understand the principle of
@FeignClient
annotations; - FeignClientsRegistrar : that is, the
@FeignClient
annotation method is used in the project. This API describes the annotation parsing method and the construction logic of the service request;
The architecture of microservice engineering is a complex and continuous process, and the components involved are also very complicated. This article only selects the three basic components of Gateway, Nacos, and Feign to make a brief summary. In the understanding of its logic, it is necessary to focus on this component. The core functions of the project and the API used by the project are used as entry points, and the source code and official documentation are often consulted.
4. Reference source code
应用仓库:
https://gitee.com/cicadasmile/butte-flyer-parent
组件封装:
https://gitee.com/cicadasmile/butte-frame-parent
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。