D
D
DiGiTAll2019-01-08 20:00:14
Nginx
DiGiTAll, 2019-01-08 20:00:14

Nginx + GoLang: how to fix what for someone?

There is a small site on laravel. Served by Nginx with the following config:

Current config
server {
  server_name mysite.com www.mysite.com;
  charset UTF-8;
  index index.php;
  disable_symmysites if_not_owner from=$root_path;
  include /etc/nginx/vhosts-includes/*.conf;
  include /etc/nginx/vhosts-resources/mysite.com/*.conf;
  access_log /var/www/httpd-logs/mysite.com.access.log;
  error_log /var/www/httpd-logs/mysite.com.error.log notice;
  ssi on;
  return 301 https://$host:443$request_uri;
  set $root_path /var/www/mysite/data/www/mysite.com/public;
  root $root_path;
  listen 185.0.0.0:80;
  location / {
   try_files $uri $uri/ /index.php?$query_string;
    location ~ [^/]\.ph(p\d*|tml)$ {
      try_files /does_not_exists @php;
    }
  }
  location @php {
    fastcgi_index index.php;
    fastcgi_param PHP_ADMIN_VALUE "sendmail_path = /usr/sbin/sendmail -t -i -f webmaster@mysite.com";
    fastcgi_pass unix:/var/www/php-fpm/mysite.sock;
    fastcgi_split_path_info ^((?U).+\.ph(?:p\d*|tml))(/?.+)$;
    try_files $uri =404;
    include fastcgi_params;
  }
  gzip on;
  gzip_comp_level 2;
  gzip_disable "msie6";
  gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript;
}
server {
  server_name mysite.com www.mysite.com;
  ssl_certificate "/var/www/httpd-cert/mysite/mysite.com_le1.crtca";
  ssl_certificate_key "/var/www/httpd-cert/mysite/mysite.com_le1.key";
  ssl_ciphers EECDH:+AES256:-3DES:RSA+AES:!NULL:!RC4;
  ssl_prefer_server_ciphers on;
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  add_header Strict-Transport-Security "max-age=31536000;";
  ssl_dhparam /etc/ssl/certs/dhparam4096.pem;
  charset UTF-8;
  index index.php;
  disable_symmysites if_not_owner from=$root_path;
  include /etc/nginx/vhosts-includes/*.conf;
  include /etc/nginx/vhosts-resources/mysite.com/*.conf;
  access_log /var/www/httpd-logs/mysite.com.access.log;
  error_log /var/www/httpd-logs/mysite.com.error.log notice;
  ssi on;
  set $root_path /var/www/mysite/data/www/mysite.com/public;
  root $root_path;
  listen 185.0.0.0:443 ssl;
  location / {
   try_files $uri $uri/ /index.php?$query_string;
    location ~ [^/]\.ph(p\d*|tml)$ {
      try_files /does_not_exists @php;
    }
  }
  location @php {
    fastcgi_index index.php;
    fastcgi_param PHP_ADMIN_VALUE "sendmail_path = /usr/sbin/sendmail -t -i -f webmaster@mysite.com";
    fastcgi_pass unix:/var/www/php-fpm/mysite.sock;
    fastcgi_split_path_info ^((?U).+\.ph(?:p\d*|tml))(/?.+)$;
    try_files $uri =404;
    include fastcgi_params;
  }
  gzip on;
  gzip_comp_level 2;
  gzip_disable "msie6";
  gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript;
}

At the same time, all possible routes on the site are known and are unlikely to change.
Let's say these:
  • mysite.com/
  • mysite.com/index.php
  • mysite.com/admin/*
  • mysite.com/blog/*
  • mysite.com/static_page_1
  • mysite.com/articles/category/*

This all works great. But the situation is complicated. At addresses like mysite.com/[a-zA-Z0-9]{2,7} there is a lot (up to 2-3K RPS with requests to the database) of specific traffic that needs to be processed. For each request, "running" Laravel is not an option at all.
And the performance drops to indecent, and the iron is all involved. To solve the problems, a small
golang server was written that listens on port 8181 on the same server. It expects data at 185.0.0.0:8181/?data=[a-zA-Z0-9]{2,7} and processes it at lightning speed. Those. The performance issue has been resolved.
It remains to make Nginx, Laravel and Go friends.
Those. Nginx should "select" all Laravel routes (they are known in advance, if they change, it is extremely rare), and the rest should be "skipped" further. The addresses of the rest (the same mysite.com/[a-zA-Z0-9]{2,7}) need to be sent for processing by the Go solution.
I tried different options with constructions like:
location @go-server {
      proxy_set_header X-Real-IP $remote_addr;
      proxy_pass http://185.0.0.0:8181;
   }

But something didn't work for me. I ask experts to help with the problem.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
V
Vladislav, 2019-01-08
@DiGiTAll

add before `location/{`

location ~ "^/([a-zA-Z0-9]{2,7})$" {
  proxy_set_header X-Real-IP $remote_addr;
  proxy_pass http://185.0.0.0:8181/?data=$1;
}

or
location ~ "^/([a-zA-Z0-9]{2,7})$" {
  try_files /does_not_exists @go-server;
}

location @go-server {
  proxy_set_header X-Real-IP $remote_addr;
  proxy_pass http://185.0.0.0:8181/?data=$1;
}

5c34dee16cecb533160256.png

B
Boris Syomov, 2019-01-08
@kotomyava

location ~* ^/[a-z0-9]{2,7}$ {
  proxy_set_header X-Real-IP $remote_addr;
  proxy_pass http://185.0.0.0:8181;
}

Also, location(s) above this may be needed if there are urls that fit this regular expression but should not be processed by the go handler. Only /admin and /blog fit in from your post:
location ~* ^/(admin|blog) {
  try_files $uri $uri/ @backend;
}

Important: This is an example showing the approach, not the final config.
In general, it is better to make a prefix so that the url go of the handler starts with it, for example: mysite.com/go/[a-zA-Z0-9]{2,7}, and then there will be no potential intersections of routes and it will be much easier to write config.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question