API gateway

Concept — — — — — — why — — — — — — how to use oclet internal concept — — — — — (upstream and downstream), routing, — — — — — ocelot internal working principle — — — — — how to do step — — — — – ocelot profile introduction, basic use routing, routing load balancing routing con? — — — — — – Sul support routing multiple service operation — — — — — — — — — — more than routing service aggregation – routing routing fuse current-limiting — – the routing cache – routing authentication.

What is an API gateway

Is used to restrict client access to the server API once the threshold is reached, as illustrated in the legend

What is the API

API is an abbreviation for Application Programming Interface. Functional approaches can be understood in real microservices. For example, if you have a microservice for a user, you can provide apis for finding users, creating users, etc.

What is a gateway

Gateway, defined on wiki.

In a computer network, a Gateway (English: Gateway) is a server that forwards communication data from other servers. When receiving a request from a client, it processes the request as if it were a source server with its own resources

Why use a microservices gateway

There are about four or four different scenarios

1. The number of aggregated microservices increases, resulting in difficult maintenance of the client

2. Aggregate microservices for clustering

2.1 To add or modify an aggregated microservice cluster, the client must be modified, resulting in client instability

2.2 Service clusters cannot solve complex balancing problems

3. Clients access multiple aggregated microservices

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

3.2 How Do I Cause the System to Break down due to Excessive Client Access

3.3 If the client accesses the microservice system, calls are made between each microservice. Time-consuming operations are hard to count.

3.4 How do I Collect client call Logs if a Client accesses the Microservice System

conclusion

1, routing,

2. Load balancing

3, current limiting

4, certification

5, authorization,

6. Link monitoring

7. Fuse downgrade

8, the Service of the Fabric

How do I use the API gateway in my project

API Gateway Types

1, Netflix Zuul + Java implementation

2, Kong nginx + Lua script implementation

3. Tyk Go language development, paid version

Developed by Ocelot Aspnetcore

How will Ocelot be used in the project

Ocelot: what is

Simply put, Ocelot is a pipe of ASP.NET Core Middleware. When it gets the request it uses a Request Builder to construct an HttpRequestMessage to the downstream real server, After the downstream service returns a response, middleware maps its returned HttpResponseMessage to an HttpResponse.

Ocelot’s inner concept

The upstream

Ocelot: Upstream

The downstream

The service mapped to Ocelot is Downstream

The main function

1, routing,

1.1 Accepting Client requests

1.2 Award client request to translate to downstream address

1.3 Invoke 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 limiting

7. Fuse downgrade

Request aggregation

9, the Service of the Fabric

And other functions

Ocelot file address

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

English document: ocelot. Readthedocs. IO/en/latest/I…

How does Ocelot use it

conditions

1, aspnetcore3.1

2, Ocelot

3. Team micro services

Ocelot. Json file

steps

1. Create an empty AspNetcore3.1 project

2. Install Ocelot through Nuget

3. Create Ocelot configuration file Ocelot

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

Note in particular that BaseUrl is our externally exposed Url, such as our Ocelot running on an address at http://123.111.1.1, but preceded by an nginx bound to the domain http://api.jessetalk.cn, So our BaseUrl here is http://api.jessetalk.cn.

4. Load ocelot. Json configuration file

public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); webBuilder.ConfigureAppConfiguration((hostingContext, Config) => {// load ocelot config.AddJsonFile("ocelot. Aggregate. }); });Copy the code

5. Configure Ocelot dependency injection and load the configuration file

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

6. Configure Ocelot middleware

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

How does Ocelot use routing

A route is configured completely
{
    "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 the code
  • Downstream is a Downstream service configuration
  • UpStream is an UpStream service configuration
  • Aggregates service aggregation configuration
  • ServiceName, LoadBalancer, UseServiceDiscovery Configures service discovery
  • AuthenticationOptions Configures service authentication
  • RouteClaimsRequirement Configures Claims authentication
  • RateLimitOptions indicates the traffic limiting configuration
  • FileCacheOptions Cache configuration
  • QosOptions quality of service and fuse
  • Forward DownstreamHeaderTransform header information
Basic Use of Routing
{
"DownstreamPathTemplate": "/api/post/{postId}",
"DownstreamScheme": "https",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 80,
}
],
"UpstreamPathTemplate": "/post/{postId}",
"UpstreamHttpMethod": [ "Get"]
}
Copy the code
  • DownstreamPathTemplate: DownstreamPathTemplate
  • DownstreamScheme: HTTP schema for downstream services
  • DownstreamHostAndPorts: address of the downstream service, if LoadBalancer is used
  • UpstreamPathTemplate: Upstream is the request Url template entered by the user
  • UpstreamHttpMethod: An upstream request HTTP method, which can use arrays
Routing 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 the code

LoadBalancer determines the algorithm for load balancing

  • LeastConnection – Send the request to the least idle server
  • RoundRobin – Take turns sending
  • NoLoadBalance – Always sent to the first request or service discovery
Route Consul load balancing

Condition:

1, the Ocelot. Provider. Consul

2, Consul

3, Ocelot

steps

1. Download Ocelot.Provider.Consul from Nuget

2. Add Consul dependency injection

Public void ConfigureServices(IServiceCollection services) {// AddOcelot to ioc container services.addocelot ().addconsul (); }Copy the code

3. Configure route Consul

{
    "DownstreamPathTemplate": "/api/posts/{postId}",
    "DownstreamScheme": "https",
    "UpstreamPathTemplate": "/posts/{postId}",
    "UpstreamHttpMethod": [ "Put" ],
    "ServiceName": "product",
    "LoadBalancerOptions": {
        "Type": "LeastConnection"
    },
}
Copy the code
Multiple route configurations (multiple items)

conditions

1, TeamService, MemberService

Ocelot. Team. Json, Ocelot. Member

steps

Create ocelot. Team. Json, ocelot. Member

2. Configure dynamic loading of 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 the code

Configuration files are automatically loaded and then merged, mainly for large project configuration

Ocelot dependency injection configuration

Public void ConfigureServices(IServiceCollection services) {// AddOcelot to ioc services.addocelot (); }Copy the 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 the code

When we request /, we combine the/Tom and/Laura results into a response return

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

Note that:

  • The aggregation service currently only supports returning JSON
  • Currently, only Get requests for downstream services are supported
  • Any downstream Response headers are discarded
  • If the downstream service returns 404, the aggregation service simply has a null value for the key and does not return 404

There are other features that will be implemented in the future

  • Slow processing of downstream services
  • Do something like GraphQL to process the result returned by the downstream service
  • The processing of 404
Routing current-limiting
"RateLimitOptions": { "ClientWhitelist": [], "EnableRateLimiting": true, "Period": "5m", "PeriodTimespan": 1, "Limit": 1}Copy the code
  • ClientWihteList white list

  • EnableRateLimiting Whether to enable traffic limiting

  • Period statistical Period: 1s, 5m, 1h, and 1d

  • PeroidTimeSpan How many seconds before the client can retry

  • Limit Indicates the maximum number of requests allowed in the statistical period

    The following configuration is also available under GlobalConfiguration

"RateLimitOptions": { "DisableRateLimitHeaders": false, "QuotaExceededMessage": "Customize Tips!" , "HttpStatusCode": 999, "ClientIdHeader" : "Test" }Copy the code
  • Whether Http headers x-rate-limit and retry-after are disabled
  • QuotaExceedMessage Message returned when request overload was truncated
  • HttpStatusCode HTTP status returned when the request overload is truncated
  • ClientIdHeader Identifies the client request header. The default value is ClientId
Routing service quality and fusing

conditions

1, the Ocelot. Provider. Polly

steps

1. Add a fuse breaker on Ocelot

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

2. Add a fuse breaker configuration

A circuit breaker means to stop forwarding requests to downstream services. Requests made when the downstream service has already failed are futile and add to the burden on the downstream server and API gateway. This functionality is implemented using Pollly, and we only need to do some simple configuration for routing

"QoSOptions": {
    "ExceptionsAllowedBeforeBreaking":3,
    "DurationOfBreak":5,
    "TimeoutValue":5000
}
Copy the code
  • ExceptionsAllowedBeforeBreaking allows many unusual request
  • DurationOfBreak Duration of a fusing, expressed in seconds
  • TimeoutValue Automatically sets the request to timeout if the downstream request takes longer to process
The routing cache

Ocelot can cache the results of downstream requests, which is not very powerful yet. It relies on CacheManager to implement it, and we just need to add the following configuration under the route

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

Region is a partition of the cache, and we can call Ocelot’s Administration API to remove the cache below a Region.

Routing authentication (Identity Server4)

conditions

1.

2,

3,

steps

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 the code

Allowed Scopes

The Scopes here will be fetched from claims in the current token, and our authentication service will rely on it for implementation. When the downstream API of the current route requires a permission, we need to declare it here. Same meaning as scope in oAuth2.

Routing authentication

After receiving claims from the AllowedScopes in the certificate, we need to add the following configuration if we want to authenticate permissions

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

Claims carried in the token of the current request context cannot access downstream services without name= “UserType” and value= “registered”.

Route request header translation

There are two types of request header forwarding: after transformation to downstream and after receiving transformation from downstream to client. In the Ocelot configuration, they are called Pre Downstream Request and Post Downstream Request. Currently the transformation only supports find and replace. We use the configuration mainly UpstreamHeaderTransform and DownstreamHeaderTransform

Pre Downstream Request

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

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

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

Post Downstream Request

We can also convert Test in the downstream Header to www.bbc.co.uk/ and forward it to the client.

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