Simple reverse proxy with a classic (blocking) message transport. The reverse proxy is implemented using the org.apache.httpcomponents
library and packaged with the maven
package manager.
- It listens to HTTP requests and forwards them to one of the instances of a downstream service that will process the requests
- Requests are load-balanced and supports multiple load-balancing strategies (Random, Round-Robin)
- After processing the request, the downstream service sends the HTTP response back to the reverse proxy
- The reverse proxy forwards the response to the client, making the initial request
- The reverse proxy is configured using the YAML specified below
- Implements an in-memory cache (Cache settings can be configured through YAML specified below)
- Implements proper logging (at the moment everything gets printed into the stdout)
The user can retrieve the information necessary to calculate some of the below-specified metrics (SLIs) from logs produced by RequesterStreamListener
, ServerExceptionListener
, ServerStreamListener
.
Category | SLI | SLO | Measure |
---|---|---|---|
HTTP Server | |||
Availability | The proportion of successful HTTP requests, as measured from the reverse proxy logs. Any HTTP status other than 500–599 is considered successful. | 99% | count of "web" http_requests which do not have a 5XX status code divided by count of all "web" http_requests |
Latency | The proportion of sufficiently fast HTTP requests, as measured from the reverse proxy logs. “Sufficiently fast” is defined as < 200 ms, or < 1,000 ms. | 90% of requests <= 200 ms 99% of requests <= 1,000 ms | count of "web" http_requests with a duration less than or equal to "0.2" seconds divided by count of all "web" http_requests - count of "web" http_requests with a duration less than or equal to "1.0" seconds divided by count of all "web" http_requests |
Throughput | The proportion of successful lightweight HTTP requests per second, as measured from the reverse proxy logs. | >= 4000 requests per second |
proxy:
loadBalancingAlgorithm: ROUND_ROBIN
listen:
address: "localhost"
port: 8080
services:
- name: some-name
domain: some-name.com
hosts:
- address: "167.99.47.15"
port: 8000
- name: some-other-name
domain: some-other-name.com
hosts:
- address: "178.62.228.77"
port: 8090
cache:
maxCacheEntries: 1000
maxObjectSize: 8192
Download the reverse proxy JAR file here.
Then run:
java -cp reverse_proxy.jar com.reverse_proxy.ReverseProxy <path-to-yaml-config>
Until the conventional logging is added, use the following command to redirect server output to the file:
java -cp reverse_proxy.jar com.reverse_proxy.ReverseProxy <path-to-yaml-config> > <log-file-name>.log 2>&1
Full example:
java -cp reverse_proxy.jar com.reverse_proxy.ReverseProxy config.yml > server.log 2>&1
- Create a helm chart to deploy the reverse proxy to a kubernetes cluster
- Add UNIT tests
- Modularize
ConfigValidator
. When something gets added or removed from the config class structure, validations need to be updated. It would be great if this scenario could be avoided so that the user can add class, specify validations on the class (@NotNull
,@NotBlank
etc.), and be done with it. Maybe use thevisitor
pattern andJava Reflection
to parse class structure and run the validators - Implement more load-balancing strategies (
Weighted Round Robin
,Least connections
etc.) - Add the
@Alias
annotation. The annotation would allow that theYAML
config names can differ from the Java class attribute names - Add
ConnectionPoolListener
- Extend listeners to log the unique ID with each request
- Forward the logs to the specific files and not to stdout
- Implement asynchronous HTTP reverse proxy