(Essence) Use of Ocelot Microservice API Gateway on September 25, 2020

(Essence) Use of Ocelot Microservice API Gateway on September 25, 2020

API gateway

Concept------why------how to use oclet-----internal concepts (upstream and downstream), routing-----ocelot internal operating principle-----how to do steps-- ---Introduction to ocelot configuration file----Basic use of routing----Routing load balancing------Routing consul support-----Routing multiple service operations-----Routing multiple service aggregation ----Route current limit----Route fuse----Route cache----Route authentication.

What is an API gateway

It is used to restrict the client's access to the server api once the threshold is reached, as shown in the legend

What is API

API is the abbreviation of Application Programming Interface, translated into Chinese is application programming interface. In actual microservices, each function method can be understood. For example, you can provide an API interface for a user service microservice, such as finding users, creating users, and so on.

What is a gateway

Gateway, defined on the wiki.

In a computer network , a gateway (English: Gateway) is a server that forwards the communication data of other servers. When receiving a request from a client, it processes the request like an origin server that owns resources.

Why use a microservice gateway

There are about 4 situations

1. The increase in aggregated microservices makes the client difficult to maintain

2. Aggregate microservices for clustering

2.1 To add and modify the aggregated microservice cluster, the client must be modified, which leads to instability of the client

2.2 Service clusters cannot solve the problem of complex balance

3. The client accesses multiple aggregated microservices

3.1 If client authentication and authorization are required, each service will be authorized

3.2 How the client access is too large to limit the client traffic, resulting in system downtime

3.3 If the client accesses the microservice system, calls are made between each microservice. Will cause time-consuming operations to be difficult to count.

3.4 If the client accesses the microservice system, how to count the client's call log

summary

1. Routing

2. Load balancing

3. Current limit

4. Certification

5. Authorization

6. Link monitoring

7. Fuse downgrade

8. Service Fabric

How to use the API gateway in the project

API gateway type

1. Netflix Zuul +java implementation

2. Kong nginx +lua script implementation

3. Tyk go language development, paid version

4. Developed by Ocelot aspnetcore

How to use Ocelot in a project

What is Ocelot

Simply put, Ocelot is a pipeline composed of a bunch of asp.net core middleware. When it gets the request, it will use a request builder to construct an HttpRequestMessage and send it to the downstream real server. After the downstream service returns the response, a middleware will map the HttpResponseMessage it returns to the HttpResponse.

Ocelot internal concept

Upstream

Ocelot is upstream: Upstream

Downstream

The service mapped below Ocelot is downstream: Downstream

The main function

1. Routing

1.1 Accept client requests

1.2 The award client request is converted into a downstream address

1.3 Call the downstream service and return the result

1.4 Return the result returned by the downstream service to the front end

2. Certification

3. Authorization

4. Load balancing

5. Link monitoring

6. Current limit

7. Fuse downgrade

8. Request aggregation

9. Service Fabric

And other functions

Ocelot document address

Chinese document: www.jessetalk.cn/2018/03/19/...

English document: ocelot.readthedocs.io/en/latest/i...

How to use Ocelot

condition

1, aspnetcore3.1

2. Ocelot

3. Team microservices

4. The ocelot.json file

step

1. Create an empty aspnetcore3.1 project

2. Install Ocelot via nuget

3. Create Ocelot configuration file ocelot.json

{ "ReRoutes": [], "GlobalConfiguration": { "BaseUrl": "https://api.mybusiness.com" } } Copy code

Pay special attention to that BaseUrl is our externally exposed Url. For example, our Ocelot runs on an address at http://123.111.1.1, but there is a nginx bound to the domain name http://api.jessetalk.cn, then Here our BaseUrl is http://api.jessetalk.cn.

4. Load the ocelot.json configuration file

public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); webBuilder.ConfigureAppConfiguration((hostingContext, config) => { //1. Load the ocelot configuration file config.AddJsonFile("ocelot.aggregate.json"); }); }); Copy code

5. Configure Ocelot dependency injection and load the configuration file

public void ConfigureServices(IServiceCollection services) { services.AddOcelot() } Copy code

6. Configure Ocelot middleware

public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseOcelot().Wait(); } Copy code

How Ocelot uses routing

Complete configuration of a route
{ "DownstreamPathTemplate": "/", "UpstreamPathTemplate": "/", "UpstreamHttpMethod": [ "Get" ], "AddHeadersToRequest": {}, "AddClaimsToRequest": {}, "RouteClaimsRequirement": {}, "AddQueriesToRequest": {}, "RequestIdKey": "", "FileCacheOptions": { "TtlSeconds": 0, "Region": "" }, "ReRouteIsCaseSensitive": false, "ServiceName": "", "DownstreamScheme": "http", "DownstreamHostAndPorts": [ { "Host": "localhost", "Port": 51876, } ], "QoSOptions": { "ExceptionsAllowedBeforeBreaking": 0, "DurationOfBreak": 0, "TimeoutValue": 0 }, "LoadBalancer": "", "RateLimitOptions": { "ClientWhitelist": [], "EnableRateLimiting": false, "Period": "", "PeriodTimespan": 0, "Limit": 0 }, "AuthenticationOptions": { "AuthenticationProviderKey": "", "AllowedScopes": [] }, "HttpHandlerOptions": { "AllowAutoRedirect": true, "UseCookieContainer": true, "UseTracing": true }, "UseServiceDiscovery": false } Copy code
  • Downstream is the downstream service configuration
  • UpStream is the upstream service configuration
  • Aggregates service aggregation configuration
  • ServiceName, LoadBalancer, UseServiceDiscovery configure service discovery
  • AuthenticationOptions configure service authentication
  • RouteClaimsRequirement Configure Claims authentication
  • RateLimitOptions is configured for current limiting
  • FileCacheOptions cache configuration
  • QosOptions service quality and circuit breaker
  • DownstreamHeaderTransform header information forwarding
Basic use of routing
{ "DownstreamPathTemplate": "/api/post/{postId}", "DownstreamScheme": "https", "DownstreamHostAndPorts": [ { "Host": "localhost", "Port": 80, } ], "UpstreamPathTemplate": "/post/{postId}", "UpstreamHttpMethod": ["Get"] } Copy code
  • DownstreamPathTemplate: downstream path template
  • DownstreamScheme: downstream service http schema
  • DownstreamHostAndPorts: The address of the downstream service, if you use LoadBalancer, you can fill in multiple items here
  • UpstreamPathTemplate: The upstream is the request Url template entered by the user
  • UpstreamHttpMethod: upstream request http method, array can be used
Route load balancing
{ "DownstreamPathTemplate": "/api/posts/{postId}", "DownstreamScheme": "https", "DownstreamHostAndPorts": [ { "Host": "10.0.1.10", "Port": 5000, }, { "Host": "10.0.1.11", "Port": 5000, } ], "UpstreamPathTemplate": "/posts/{postId}", "LoadBalancerOptions": { "Type": "LeastConnection" }, "UpstreamHttpMethod": ["Put", "Delete"] } Copy code

LoadBalancer will determine the algorithm of load balancing

  • LeastConnection-send the request to the server that is the least available
  • RoundRobin-send in turn
  • NoLoadBalance-always sent to the first request or service discovery
Routing Consul load balancing

condition:

1. Ocelot.Provider.Consul

2. Consul

3. Ocelot

step

1. Download Ocelot.Provider.Consul via nuget

2. Add consul dependency injection

public void ConfigureServices(IServiceCollection services) { //1. Add the gateway Ocelot to the ioc container services.AddOcelot().AddConsul(); } Copy code

3. Routing consul configuration

{ "DownstreamPathTemplate": "/api/posts/{postId}", "DownstreamScheme": "https", "UpstreamPathTemplate": "/posts/{postId}", "UpstreamHttpMethod": ["Put" ], "ServiceName": "product", "LoadBalancerOptions": { "Type": "LeastConnection" }, } Copy code
Multiple routing configurations (multi-project)

condition

1. TeamService, MemberService

2. ocelot.team.json, ocelot.member.json

step

1. Create ocelot.team.json, ocelot.member.json files

2. Configure to dynamically load the ocelot.json configuration file

webBuilder.ConfigureAppConfiguration((hostingContext, config) => { config //.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath) //.AddJsonFile("appsettings.json", true, true) //.AddJsonFile($"appsettings.{hostingContext.HostingEnvironment.EnvironmentName}.json", true, true) .AddOcelot(hostingContext.HostingEnvironment); //.AddEnvironmentVariables(); }); Copy code

The configuration file will be automatically loaded and then merged, mainly used for large project configuration

3. Ocelot dependency injection configuration

public void ConfigureServices(IServiceCollection services) { //1. Add the gateway Ocelot to the ioc container services.AddOcelot(); } Copy code
Route aggregation request
{ "ReRoutes": [ { "DownstreamPathTemplate": "/", "UpstreamPathTemplate": "/laura", "UpstreamHttpMethod": [ "Get" ], "DownstreamScheme": "http", "DownstreamHostAndPorts": [ { "Host": "localhost", "Port": 51881 } ], "Key": "Laura" }, { "DownstreamPathTemplate": "/", "UpstreamPathTemplate": "/tom", "UpstreamHttpMethod": [ "Get" ], "DownstreamScheme": "http", "DownstreamHostAndPorts": [ { "Host": "localhost", "Port": 51882 } ], "Key": "Tom" } ], "Aggregates": [ { "ReRouteKeys": [ "Tom", "Laura" ], "UpstreamPathTemplate": "/" } ] } Copy code

When we request/, the two results of/tom and/laura will be merged into one response and returned

{"Tom":{"Age": 19},"Laura":{"Age": 25}} Copy code

have to be aware of is:

  • The aggregation service currently only supports returning json
  • Currently only supports the Get method to request downstream services
  • Any downstream response headers will be discarded
  • If the downstream service returns 404, the aggregation service is just that the value of this key is empty, it will not return 404

There are some other functions that will be implemented in the future

  • Slow processing of downstream services
  • Do some processing like GraphQL to process the results returned by downstream services
  • 404 handling
Route current limit
"RateLimitOptions": { "ClientWhitelist": [], "EnableRateLimiting": true, "Period": "5m", "PeriodTimespan": 1, "Limit": 1 } Copy code
  • ClientWihteList whitelist

  • EnableRateLimiting Whether to enable current limiting

  • Period Statistical time period: 1s, 5m, 1h, 1d

  • PeroidTimeSpan how many seconds after the client can retry

  • Limit The maximum number of requests allowed in the statistical time period

    We can also perform the following configurations under GlobalConfiguration

"RateLimitOptions": { "DisableRateLimitHeaders": false, "QuotaExceededMessage": "Customize Tips!", "HttpStatusCode": 999, "ClientIdHeader": "Test" } Copy code
  • Whether Http header X-Rate-Limit and Retry-After are disabled
  • QuotaExceedMessage The message returned when the request is overloaded and truncated
  • HttpStatusCode The http status returned when the request is overloaded and truncated
  • ClientIdHeader is used to identify the client's request header, the default is ClientId
Routing service quality and circuit breaker

condition

1. Ocelot.Provider.Polly

step

1. Add a fuse on ocelot

public void ConfigureServices(IServiceCollection services) { //1. Add the gateway Ocelot to the ioc container services.AddOcelot(new ConfigurationBuilder().AddJsonFile("ocelot.aggregate.json").Build()) .AddConsul() .AddPolly(); } Copy code

2. Add fusing configuration

Fuse means to stop forwarding requests to downstream services. When the downstream service has failed, the re-request will also be rewarded, and will increase the burden on the downstream server and API gateway. This function is implemented by Pollly, we only need to do some simple configuration for routing

"QoSOptions": { "ExceptionsAllowedBeforeBreaking":3, "DurationOfBreak":5, "TimeoutValue":5000 } Copy code
  • ExceptionsAllowedBeforeBreaking how many exception requests are allowed
  • DurationOfBreak fusing time, in seconds
  • TimeoutValue If the processing time of the downstream request exceeds how much time, the request is automatically set to timeout
Route cache

Ocelot can cache the results of downstream requests, but the current cache function is not very powerful. It mainly relies on CacheManager to achieve, we only need to add the following configuration under the route

"FileCacheOptions": {"TtlSeconds": 15, "Region": "somename" } Copy code

Region is a partition of the cache. We can call Ocelot's administration API to remove the cache under a certain region.

Routing authentication (Identity Server4)

condition

1,

2,

3.

step

Identity Server Bearer Tokens

The same is true for adding Identity Server authentication

public void ConfigureServices(IServiceCollection services) { var authenticationProviderKey = "TestKey"; var options = o => { o.Authority = "https://whereyouridentityserverlives.com"; o.ApiName = "api"; o.SupportedTokens = SupportedTokens.Both; o.ApiSecret = "secret"; }; services.AddAuthentication() .AddIdentityServerAuthentication(authenticationProviderKey, options); services.AddOcelot(); } Copy code

Allowed Scopes

The scopes here will be obtained from the claims in the current token, and our authentication service will rely on it to achieve. When the downstream API of the current route requires a certain permission, we need to declare it here. It has the same meaning as scope in oAuth2.

Route authentication

After we get the claims through the AllowedScopes in the certification, if we want to authenticate the permissions, we need to add the following configuration

"RouteClaimsRequirement": { "UserType": "registered" } Copy code

If the claims carried in the token of the current request context do not have name= UserType and value= registered , then downstream services cannot be accessed.

Route request header conversion

There are two types of request header forwarding: sending it to the downstream after conversion and sending it to the client after receiving the conversion. It is called Pre Downstream Request and Post Downstream Request in Ocelot's configuration. The current conversion only supports search and replace. The configuration we use is mainly UpstreamHeaderTransform and DownstreamHeaderTransform

Pre Downstream Request

"Test": "http://www.bbc.co.uk/, http://ocelot.com/"Copy code

For example, we change the Test value in the Header passed by the client to ocelot.com/and then pass it to the downstream

"UpstreamHeaderTransform": { "Test": "http://www.bbc.co.uk/, http://ocelot.com/" }, Copy code

Post Downstream Request

And we can also transfer the Test in the downstream Header to www.bbc.co.uk/and then transfer it to the client.

"DownstreamHeaderTransform": { "Test": "http://www.bbc.co.uk/, http://ocelot.com/" }, Copy code