This is the 16th day of my participation in the November Gwen Challenge. Check out the event details: The last Gwen Challenge 2021
Recently, I need to implement a small tool to forward POST requests to a specified back-end service. Since I always want to learn gin framework, I will try to use this framework and expect to produce several articles. This paper studies how to use nginx containers and back-end services to test the forwarding tool.
An overview of the
The tool of forwarding is relatively simple to implement, but in order to verify, it is also necessary to use other tools to cooperate, this paper writes its own back-end program, and uses Nginx to realize the forwarding of several back-end programs. For ease of understanding, an example diagram is given below. Forwarding without nginx is shown below:
Using Nginx to achieve forwarding is shown in the following figure:
Note 1: The two images are similar. Note the URL changes in the images. Note 2: In this article, the client can bypass nginx to directly access the back-end service, which is not a good idea in practice and will not be considered in depth for demonstration purposes only.
The back-end service
The simple back-end service response functions implemented in the previous article are not listed here. It should be noted that since this series of forwarding and back-end use the same set of code, if you want to start the back-end service in the program, you must change the name of the back-end service executable file, refer to the previous code.
The nginx container starts and restarts
This article uses mirrored centos/nginx-116-centos7 for testing. The simple boot is as follows:
docker run -itd --name nginx -p 8080:8080 -v $PWD:/opt/bin centos/nginx-116-centos7 bash
Copy the code
Docker-comemage. yml: docker-comemage. yml: docker-comemage. yml: docker-compose
version: '2' services: nginx: image: centos/nginx-116-centos7 container_name: nginx command: /bin/bash -c "/home/latelee/bin/run.sh" volumes: - $PWD/bin:/home/latelee/bin - $PWD/nginx/log:/var/opt/rh/rh-nginx116/log/nginx - $PWD/nginx/etc:/etc/nginx - /etc/localtime:/etc/localtime #environment: # - ORACLE_HOME=/work/instantclient_12_1 # - TNS_ADMIN=$ORACLE_HOME ports: - 8080:8080-8090:8090Copy the code
Note: Backend servers (and startup scripts) and nginx configuration files are placed in the host directory because it is easier to update.
To run custom commands during container startup, you need to disable background execution of the nginx service. The startup script run.sh contains the following contents:
#! /bin/bash echo "run..." cd /home/latelee/bin nginx -g "daemon off;" & sleep 1 ./httpforward.exe -p 8090Copy the code
How to start nginx in a container
If you add a custom CMD in the Dockerfile, be sure to include -g daemon off; in the CMD in order for nginx to stay in the foreground, so that Docker can track the process properly (otherwise your container will stop immediately after starting)!
-g daemon off must be added to start a custom command, otherwise the container will exit automatically after the custom command is started.
Start container:
docker-compose up -d
Copy the code
View logs:
docker-compose logs -f
Copy the code
Nginx is already started by default. If the configuration is modified. You can restart the container or within the container using the nginx -s reload command. Nginx -s supports only four parameters: stop, quit, reopen, reload. The official document calls these parameters signal. If you execute nginx -s stop stop nginx, restart again, you will be prompted nginx: [error] open () “/ var/opt/rh/rh – nginx116 / run/nginx/nginx. Pid” failed (2: No such file or directory). Therefore, after modifying the nginx configuration, use reload.
Some tests for nginx forwarding
The nginx configuration file is /etc/nginx/nginx.conf in both the container and the physical machine. In fact, nginx also reads the /etc/nginx/conf.d directory, which is beyond the scope of this article.) After modifying this file, you must perform nginx -s reload to restart nginx. The configuration of location is generally as follows:
Location /fee/9000 {proxy_pass http://127.0.0.1:9000; proxy_set_header Host $proxy_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }Copy the code
Requests sent to the nginx server, if the URL is /fee/9000, are forwarded to the local service on port 9000. (Note: /fee/9000 can continue to add suffix urls, but is not the scope of this discussion), other retweets are similar. After testing, specify the back-end service address directly with the proxy_pass field. As follows:
Location /fee/9000 {proxy_pass http://127.0.0.1:9000; }Copy the code
Tests found that when using the above forwarding rules, a back-end program must be implemented/fee / 9000 response, namely can normal request http://127.0.0.1:9000/fee/9000 in the container. If not, a 404 is prompted. The backend of this article cannot respond to a URL with a suffix.
After checking, adding a slash/after the URL of the back-end program can solve the problem as follows:
Location /fee/9000 {proxy_pass http://127.0.0.1:9000/; }Copy the code
The comparison is as follows:
Do not add slash: http://127.0.0.1:8080/fee/9000 - > http://127.0.0.1:9000/fee/9000 add slash: http://127.0.0.1:8080/fee/9000 - > add slash extension: http://127.0.0.1:9000/ http://127.0.0.1:8080/fee/9000/foo - > http://127.0.0.1:9000/fooCopy the code
For the author’s application, the URL of the request back-end program must be in the form of http://127.0.0.1:9000/, no additional suffixes can be added. Due to the lack of in-depth research on Nginx, the discussion will not be carried out temporarily.
The experimental results
Request command:
POST - F $curl http://192.168.28.11:8090/fee/test - X "file = @ sample. Json" % % of Total Received % Xferd business, Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 434 100 98 100 336 3920 13440 --:--:-- --:--:-- --:--:-- 18083{"code":0,"data":{"result":"ok in back end server, port: 9001 info: run in port 9001"},"msg":"ok"}Copy the code
Forwarding tool:
nginx | got url: http://127.0.0.1:8080/fee/9001
nginx | [GIN] 2021/11/14 - 11:45:30 | 200 | 10.002826ms | 192.168.28.5 | POST "/fee/test"
Copy the code
Nginx log:
==> nginx/log/access.log <== 127.0.0.1 - - [14/Nov/ 201:11:45:30 +0800] "POST /fee/9001 HTTP/1.1" 200 98 "- "Go - HTTP client / 1.1" "-"Copy the code
summary
In this article, the self-written forwarding tool manages and configures the backend and nginx by starting several backend programs, assigning port numbers (starting with 9000) and urls according to rules, writing them to an Nginx configuration file, and finally restarting the Nginx service. Of course, these are the easier ways to do it. In starting the back-end program, I spent some time troubleshooting problems because I used the same code. It also took quite a bit of time (about two late nights) to test nginx forwarding urls.
In the follow-up, the author will study how to self-implement the load balancing algorithm. — I’ve been planning to do this for more than half a year. Take this opportunity to spare some time to do it.
reference
The discussion about forwarding URL stackoverflow.com/questions/4… Nginx image: hub.docker.com/_/nginx