Nginx 通过反向代理在多个平台接入上游的客户信息

感谢

  • 美滋滋的nginx
  • 百度上大佬写的blog
  • laravel
  • silber/page-cache

需要实现的功能

  • 在多个不同的平台(可能不在同一个服务器)接入同一个上游的客户信息
  • 客户相关页面实现静态页面

前提

  • 我使用的是laravel框架
  • 所有的客户信息都保存在上游网站http://push.push.do中,每个用户拥有一个唯一的标识(tag),用于识别客户,之后我所说的上游都是表示http://push.push.do
  • 现在 http://pingtai.do需要接入上游网站的客户信息,标识为client的客户在此平台的二级域名为http://client.pingtai.do
  • http://pingtai.do只使用了@和www两个解析
  • push.push.do 解析地址 127.0.0.1
  • pingtai.do 解析地址 127.0.0.2

分析

  1. 一开始的时候,我想用linux提供的软连接的方式来做,但是因为后来得知每个平台可能在不同的服务器上,veto~
  2. 然后开始尝试使用nginx的反向代理来实现

反向代理操作步骤

  1. 域名解析

pingtai.do做泛域名解析,解析地址为127.0.0.2

  1. 基础的反向代理

添加*.pingtai.do的nginx配置,这里需要注意www.pingtai.dopingtai.do的配置文件不要去动他

分两个server模块是为了不影响平台本身实现的功能

server {
    listen 80;
    server_name pingtai.do www.pingtai.do;

    ...
}

server {
    listen 80;
    server_name ~^(.*?).pingtai.do$; #这里使用了正则的捕获,我需要请求地址中的客户唯一标识来识别客户

    ...

    location / {
        proxy_pass http://push.push.do; #反向代理到拥有全部客户信息的上游地址

        proxy_redirect             off; 
        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; 
        proxy_set_header           RequestUrl $host; #将请求地址发送给上游
        proxy_set_header           Domain $1; #将客户唯一标识发送给上游
        client_max_body_size       10m;
        client_body_buffer_size    128k;
        proxy_connect_timeout      300;
        proxy_send_timeout         300;
        proxy_read_timeout         300;
        proxy_buffer_size          4k;
        proxy_buffers              4 32k;
        proxy_busy_buffers_size    64k;
        proxy_temp_file_write_size 64k;
        #其他的这些配置都是我直接百度的,需要知道作用,请自行百度
    }

    ...
}
  1. http://push.push.do的程序的routes/web.php中实现对应的路由
    //其他的解析对应的路由
    ...

    //因为push.do上还有其他的解析,使用laravel提供的子域名路由功能
    Route::group(['domain' => 'push.push.do', 'namespace' => 'Client'], function () {
    //客户二级域名首页
    Route::get('/', 'IndexController@index')->name('client.index');
    //客户模块信息列表页面
    Route::get('{chunk}','ChunkController@index')->name('client.chunk');
    //客户单页信息页面
    Route::get('{page}.html','PageController@index')->name('client.page');
    //客户详细信息页面
    ROute::get('{chunk}/{info}.html','InfoController@pc')->name('client.info');

    //还有手机站的路由 我没写
});
  1. 到了这一步,基本上就实现了反向代理了("=>"标识请求对应的上游)
  • http://client.pingtai.do => http://push.push.do
  • http://client.pingtai.do/product => http://push.push.do/product
  • http://client.pingtai.do/about.html => http://push.push.do/about.html
  • http://client.pingtai.do/product/1.html => http://push.push.do/product/1.html
  1. 得到客户唯一标识,识别客户
//很简单 因为我再反向代理时设置了头信息,可以在push.push.do的程序中使用laravel提供的方法简单的得到

request()->server('HTTP_DOMAIN')#使用唯一标识去查询数据库得到用户信息
  1. 渲染页面

既然都得到了客户的信息,渲染页面也就很简单的 查询相关信息,然后渲染到blade模版就ok了

静态页面生成操作步骤

  1. 静态页面?

为了加快速度,在第一次访问客户页面的时候我希望将渲染的页面保存为静态页面,要是在用nginx的gzip压缩一下,那就美滋滋了

我使用了silber/page-cache这个拓展来生成(做了一点修改)静态页面

  1. 安装silber/page-cache

  2. 修改silber/page-cache默认生成静态页面的位置,加入客户唯一标识做路径

//修改文件vendor/silber/page-cache/src/Cache.php的getDefaultCachePath方法
protected function getDefaultCachePath()
{
    if ($this->container && $this->container->bound('path.public')) {
        return $this->container->make('path.public') . '/page-cache/' . request()->server('HTTP_DOMAIN');
    }
}

//这里的request()->server('HTTP_DOMAMIN') 就是之前提到的客户唯一标识
  1. 修改http://push.push.do的nginx配置,来实现静态页面的反向代理
server {
    listen 80;
    server_name push.push.do;

    ...

    # 开启了gzip 美滋滋    
    gzip on;

    #这是首页的实现(有静态页面就用静态页面,没有就正常访问程序)
    location = / {
        try_files /page-cache/$http_domain/pc__index__pc.html /index.php?$query_string;
    }

    #这是其他的静态页面(有静态页面就用静态页面,没有就正常访问程序)
    location / {
        try_files $uri $uri/ /page-cache/$http_domain/$uri.html /index.php?$query_string;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass php_upstream;      
        #fastcgi_pass unix:/run/php/php7.0-fpm.sock;
    }

    charset utf-8;

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }
    location ~ /\.ht {
        deny all;
    }
}
  1. 认证阅读silber/page-cache的文档后,我们知道怎么生成静态页面
//只要添加一个中间件就好了
$this->middleware('page-cache');

封面来源

封面图片来自https://learnku.com/laravel/t/7939/extension-recommendation-josephsilberpage-cache-laravel-static-page-caching,如有冒犯,可以联系我

End

上一篇: Leetcode PHP题解--D78 206. Reverse Linked List

下一篇: Leetcode基础刷题之PHP解析(17. Letter Combinations of a Phone Number)