I am trying to understand the main difference between
(1) Using a reverse-proxy such as Nginx or Envoy as a gateway to route requests to corresponding microservice
vs
(2) Building a custom solution which uses the HttpClient (in .Net) to forward the request to the corresponding microservice. I would like to understand the benefits and drawbacks of each approach.
I think that the first approach Layer 7 routing, is that mean it is more performant than the second.
I agree with wander3r. I'm using envoy currently as my API proxy. With envoy, it's not only act as proxy but also handle logging, load balancing, rate limiting, circuit breaking etc.
If you are new to envoy. i did a simple step by step guide on how to start using envoy proxy.
Envoy Proxy Guide
Related
Background
I came from HAproxy background and recently there is a lot of hype around "Service Mesh" Architecture. Long story short, I began to learn "Envoy" and "Consul".
I develop an understanding that Envoy is a proxy software but using sidecar to abstract in-out network with "xDS" as Data Plane for the source of truth (Cluster, Route, Filter, etc). Consul is Service Discovery, Segmentation, etc. It also abstracts network and has Data Plane but Consul can't do complex Load Balancing, filter routing as Envoy does.
As Standalone, I can understand how they work and set up them since documentation relatively good. But it can quickly became a headache if I want to integrate Envoy and Consul, since documentation for both Envoy & Consul lacks specific for integration, use-cases, and best practice.
Schematic
Consider the following simple infrastructure design:
Legends:
CS: Consul Server
CA: Consul Agent
MA: Microservice A
MB: Microservice B
MC: Microservice C
EF: Envoy Front Facing / Edge Proxy
Questions
Following are my questions:
In the event of Multi-Instance Microservices, Consul (as
stand-alone) will randomize round-robin. With Envoy & Consul
Integration, How consul handle multi-instance microservice? which
software does the load balance?
Consul has Consul Server to store its data, however, it seems Envoy
does not have "Envoy Server" to store its data, so where are its
data being stored and distributed across multiple instances?
What about Envoy Cluster (Logical Group of Envoy Front Facing Proxy
and NOT Cluster of Services)? How the leader elected?
As I mentioned above, Separately, Consul and Envoy have their
sidecar/agent on each Machine. I read that when integrated, Consul
injects Envoy Sidecar, but no further information on how this works?
If Envoy uses Consul Server as "xDS", what if for example I want to
add an advanced filter so that for certain URL segment it must
forward to a certain instance?
If Envoy uses Consul Server as "xDS", what if I have another machine
and services (for some reason) not managed by Consul Server. How I
configure Envoy to add filter, cluster, etc for that machine and
services?
Thank You, I'm so excited I hope this thread can be helpful to others too.
Apologies for the late reply. I figure its better late than never. :-)
If you are only using Consul for service discovery, and directly querying it via DNS then Consul will randomize the IP addresses returned to the client. If you're querying the HTTP interface, it is up to the client to implement a load balancing strategy based on the hosts returned in the response. When you're using Consul service mesh, the load balancing function will be entirely handled by Envoy.
Consul is an xDS server. The data is stored within Consul and distributed to the agents within the cluster. See the Connect Architecture docs for more information.
Envoy clusters are similar to backend server pools. Proxies contain Clusters for each upstream service. Within each cluster, there are Endpoints which represent the individual proxy instances for the upstream services.
Consul can inject the Envoy sidecar when it is deployed on Kubernetes. It does this through a Kubernetes mutating admission webhook. See Connect Sidecar on Kubernetes: Installation and Configuration for more information.
Consul supports advanced layer 7 routing features. You can configure a service-router to route requests to different destinations by URL paths, headers, query params, etc.
Consul has an upcoming feature in version 1.8 called Terminating Gateways which may enable this use case. See the GitHub issue "Connect: Terminating (External Service) Gateways" (hashicorp/consul#6357) for more information.
Let's say I have a Kubernetes Job that makes https requests to changing URLs and I want to allow specific URLs only and block all other requests. My idea is deploy an Https-Proxy-Pod and use NetworkPolicies to make sure the Job-Pod can only communicate with the Https-Proxy-Pod. See following sketch for better understanding:
sketch of https-proxy sidecar deployment
I know how to do that but have no idea what Https Proxy to use. As far as I understood envoy is not a suitable solution for what I want to do: https://github.com/envoyproxy/envoy/issues/1606
Does anyone has a better solution or can tell me which proxy to use?
Mitmproxy is an open source tool that you can use to filter HTTP and HTTPS requests transparently using the Python scripting language.
There's also a quite detailed tutorial on how to use it
I have a system with microservice architecture. So I have a setup such that when I hit an URL, for example "http://localhost:8081/data/myId/" I get back a JSON response describing a resource. This is the system which I have created.
It turns out that there is some more complexity as to get this response, I am making a connection to an external service provider - this is what I want to use WireMock to mock, as this service provider has an API call limit. Let us say that I am interacting with this service provider at the following URL "https://api.dummyservice.com/". (So all "http://localhost:8081/data/myId/" calls consist of a "https://api.dummyservice.com/" call.)
So I am using WireMock as follows
java -jar '/home/user/Desktop/wiremock-standalone-2.19.0.jar'
--recd-mappings
--proxy-all https://api.dummyservice.com/
--verbose
--print-all-network-traffic
My intention is to listen to all calls at https://api.dummyservice.com/ through my microservice-based system so that I can stub and mock the responses. The problem is that I am not capturing any traffic at all when I access "http://localhost:8081/data/myId/" and get a successful response back!
Have I misunderstood WireMock's application? How can I debug this issue? It seems that I am performing quite a straightforward task.
I am on an Ubuntu 18.04 system if it makes any difference.
It seems you use standalone WireMock in a proper way, but please check correct params here
--record-mappings
--proxy-all="https://api.dummyservice.com/"
I have 3 Web API Servers which have the same functionality. I am going to add another Web API server which will be used only for Proxy. So All clients from anywhere and any devices will call Web API Proxy server and the Proxy server will transfer randomly the client requests to the other 3 Web API servers.
I am doing this way because:
There are a lot of client requests in a minute and I can not use only 1 Web API server.
If one server was dead, clients can still send request to the other servers. (I need at least 1 web servers response to the clients )
The Question is:
What is the best way to implement the Web API Proxy server?
Is there a better way to handle high volume client requests?
I need at least 1 web server response to the clients. If I have 3 servers and 2 of them are dead.
Please give me some links or documents that can help me.
Thanks
Sounds like you need a reverse proxy. Apache HTTP Server and NGINX can be configured to act as a load balanced reverse proxy.
NGINX documentation: http://nginx.com/resources/admin-guide/reverse-proxy/
Apache HTTP Server documentation: http://httpd.apache.org/docs/2.2/mod/mod_proxy.html
What you are describing is call Load Balancing and Azure (which seems you are using from your comments) provides it out of the box both for Cloud Services and Websites. You should create as many instances as you like under the same cloud service and open a specific port (which will be load balanced) under cloud service endpoints.
I'm reading up on SockJS node server. Documentation says:
Often WebSockets don't play nicely with proxies and load balancers. Deploying a SockJS server behind Nginx or Apache could be painful. Fortunately recent versions of an excellent load balancer HAProxy are able to proxy WebSocket connections. We propose to put HAProxy as a front line load balancer and use it to split SockJS traffic from normal HTTP data.
I'm curious if anyone can expand on the problem that is being solved by HAProxy in this case? Specifically:
Why websockets don't play nice with proxies and load balancers?
Why deploying Sockjs sever behind Apache is painful?
1. Why websockets don't play nice with proxies and load balancers?
I'd recommend you read this article on How HTML5 Web Sockets Interact With Proxy Servers by Peter Lubbers. It should cover everything you need to know about WebSocket and proxies - and thus, load balancers.
2. Why deploying Sockjs sever behind Apache is painful?
There is a module for handling WebSocket connections but at present Apache doesn't natively support WebSocket, nor does it look like it will any time soon based on this bug filed on apache - HTML5 Websocket implementation. The suggestion is that it actually fits the module pattern better.
So, it's "painful" simply because it's not easy - there's no official support and therefore it doesn't have the community use that it otherwise may have.
There may also be other pains in the SockJS has HTTP-based fallback transports. So you need to proxy both the WebSocket connections (using the apache-websocket module) and also HTTP requests when fallback is used.
Related to this: Nginx v1.3 was released in February with WebSocket support.