成文时间: 2018-11-29 11:18:10

环境说明
Ubuntu 16.04 LTS
Nginx version: nginx/1.10.3 (Ubuntu)
PHP 7.1.18
Laravel 5.5

需求说明

微信开发类项目,需要要调试微信接口,本地开发上可以采用微信开发者工具和微信测试公众号模拟运行环境和接口。但有部分微信商户号的接口例如微信支付,目前需要用沙盒模拟的方式开发,不够方便。
因此,我们想要构建一个能用于微信开发项目的线上测试环境,能调取到真实微信公众号的接口方便线上测试。

思路

要构建线上测试环境最直接的想法就是额外购买一台硬件参数、环境配置与生产环境服务器完全一致的服务器。对接微信平台方面,还需额外注册一个开通微信认证的微信公众号。
这么做虽然能解决问题,但增加了额外成本,而且增加了服务器、微信账号等等的额外维护工作,对于我们这种初创技术团队来讲不是上策。

有没有更低成本和更便于系统维护迭代的方案呢?
经过一番折腾,我们摸索出如下方案,分享出来欢迎交流。

解决方案分享

问题的关键在于如何解决解决微信接入问题

做过微信开发的朋友都知道,接入微信,需要在微信公众号后台填写一个绑定服务器的备案域名

问题是 URL 这一项,可填值是唯一的且区分子域名。 例如:

www.project.com/login 指向生产环境 dev.project.com/login 指向线上测试环境 那么微信公众号只能选择接入一个域名。

我们采取Nginx反向代理的功能去解决,即当请求访问 www.project.com 这一域名,Nginx服务器通过路径规则匹配,实现请求转抛,以指向不同的项目目录。 例如:

www.project.com/login 指向生产环境 www.project.com/dev/login 指向线上测试环境

我们通过配置 Nginx 服务器,使得请求匹配到 /dev/ 则将请求转抛给测试环境下的项目去处理

下面是 Nginx 配置的代码实现

代理管理配置文件 /etc/nginx/sites-available/project.proxy.conf

server {listen 80;server_name 127.0.0.1 www.project.com;index index.html index.php;charset utf-8;access_log /var/log/nginx/project.proxy.access.log;error_log /var/log/nginx/project.proxy.error.log;# 生产环境location / {proxy_pass http://127.0.0.1:9001;proxy_set_header Host $host:$server_port;}# 线上测试环境location ^~ /dev/ {proxy_pass http://127.0.0.1:9002;proxy_set_header Host $host:$server_port;}
}复制代码

除了 Nginx 服务器的配置,还需要对项目的配置环境做设置。 主要是进入项目的请求加上统一前缀,这个不同框架有不同的实现,下面仅以 php 框架 Laravel 为例: Laravel 项目下, 先在 .env 配置环境中增加变量 PREFIX

PREFIX=/dev  // 前面加 / 是为了解决后续静态资源处理的问题,算是一个小坑
复制代码

然后修改 app/Providers/RouterServiceProvider.php 文件中的 mapWebRouters() :

protected function mapWebRoutes(){// 从配置文件中获取前缀$prefix = env("PREFIX") === "" ? "" : explode('/',env("PREFIX"))[1];Route::prefix($prefix) // 给路由添加统一前缀 ->middleware('web')->namespace($this->namespace)->group(base_path('routes/web.php'));}
复制代码

实际部署中生产环境和线上测试环境的 .env 文件中的 PREFIX 分别配置为 "" 和 "/dev" 即可。

到这里,本以为万事俱备。
一访问却发现静态文件404。
排查后发现,问题在于静态文件引用路径,例如:

<script src="/dev/test/test.js"></script>
复制代码

实际页面访问时,这个资源请求路径会被拼接上域名,即最终变为:

www.project.com/dev/test/te…

而 Laravel 的静态资源全部放置在 public 目录下,由于添加了统一路由前缀,所以上面的 URL 并不会指向 public 目录所在的资源目录,而是被当作路由请求处理了...

最终我的处理方案是,修改 Nginx 配置,对请求的 URI 路径做规则校验,匹配到 .js 或 .css 结尾的请求,去除 URL 中的 /dev/ 字符串。

修改后的 /etc/nginx/sites-available/project.proxy.conf 配置代码如下:

server {listen 80;server_name 127.0.0.1 www.project.com;index index.html index.php;charset utf-8;access_log /var/log/nginx/project.proxy.access.log;error_log /var/log/nginx/project.proxy.error.log;# 生产环境location / {proxy_pass http://127.0.0.1:9001;proxy_set_header Host $host:$server_port;}# 线上测试环境location ^~ /dev/ {proxy_pass http://127.0.0.1:9002;# 静态资源过滤 /dev/if ($request_uri ~* .(?:js|css)$) {rewrite /dev/(.+)$ /$1 break;}proxy_set_header Host $host:$server_port;}
}
复制代码

现在当访问

www.project.com/dev/test/te…

请求转抛后,会被处理成

www.project.com/test/test.j…

因此能正常访问到 Laravel 项目中的 public 资源目录

坑记录

过程中还是踩了不少的坑:

  1. Nginx 服务器代理配置时
proxy_set_header Host $host:$server_port;
复制代码

这行代码必不可少,否则初次访问 www.project.com/dev/login 能去到正确目录,但后续项目内所有请求都会被设置为 http://127.0.0.1:9002 开头...

  1. 项目中的静态资源引用路径也要改变,如:
<script src="/dev/test/test.js"></script>
复制代码

上面的是编译后的运行代码,实际开发时的代码应该是( Laravel 框架的 blade 模板语法):

<script src="{{ env('PREFIX') }}/test/test.js"></script>
复制代码
  1. 静态资源方面还存在的隐患,如果资源是异步引用的,那就凉凉。这种情况多出现在引用工具库,另外在引用图片等静态资源方面也会比较麻烦...

待优化问题

静态资源引用方面存在的隐患促使需要更优解决方案,目前想到的优化方案是:

  1. 静态资源全部采用 CDN 方式引用,避免路径问题。
  2. 样式 icon 全部采用 font-icon 方式,避免图标元素的路径问题。

总结

本文主要分享了单一服务器构建微信项目线上测试环境的方式(同一个公众号),主要有以下要点:

  1. 通过 Nginx 反向代理机制,实现请求分发
  2. 通过 项目环境配置,实现请求在项目内添加统一路由前缀
  3. 项目中静态资源路径问题导致的坑,对此的处理方法及优化思路

参考文献:

nginx 配置之 proxy_pass 神器!
proxy_pass反向代理配置中url后面加不加/的说明
laravel获取当前的url以及当前的基础域名方法汇总
Nginx中if语句中的判断条件

Nginx 反向代理实现微信开发完美线上测试环境相关推荐

  1. 使用nginx反向代理在微信小程序中使用http请求

    使用nginx反向代理在微信小程序中使用http请求 由于微信小程序对第三API的请求做了限制官方说明文档,导致我们无法访问非https的请求,然而我们在开发小程序过程中所请求的第三方接口不一定都是h ...

  2. 报错——Nginx反向代理400错误

    Nginx反向代理400错误 一.Nginx反向代理400错误原因分析及纠错 一.Nginx反向代理400错误原因分析及纠错 实验环境:一台nginx服务器,两台tomcat服务器,实验是进行ngin ...

  3. 微信公众号开发---nginx反向代理

    nginx反向代理网上资料也很多,最主要的是proxy_set_header Host  设置 和 proxy_pass 设置,这里设置为natapp分配的域名(免费域名当天有效,所以每天都要重启并重 ...

  4. MacOS开发必备工具brew,安装nginx反向代理,替代linux工具 apt-get和 yum...

    Mac os开发者必备工具 brew,替代Linux系统中的 apt-get和yum工具,本文介绍Mac电脑安装Homebrew,并下载安装软件nginx反向代理过程. 1.安装Homebrew 在苹 ...

  5. 使用Nginx反向代理豆瓣Api电影接口(解决微信小程序频繁调用api被关小黑屋)

    首先你要知道什么是Nginx服务器,这个问题百度明白之后继续查看此文章 (要学会自己动手自己独立思考哦) 直接贴代码 ①小程序调用api需要要是https模式才行,https申请请去自己买的云服务器端 ...

  6. 2022年4月10日记:Linux服务器开发,King,Nginx反向代理与系统参数配置conf原理

    Nginx反向代理与系统参数配置conf原理 前言 nginx成功开源的原因: nginx三个可控入口: 惊群 总结 前言 今天学习Nginx反向代理,可以说是慕名而来.从整体上看,我对Nginx的了 ...

  7. nginx反向代理原理及配置详解

    nginx概述 nginx是一款自由的.开源的.高性能的HTTP服务器和反向代理服务器:同时也是一个IMAP.POP3.SMTP代理服务器:nginx可以作为一个HTTP服务器进行网站的发布处理,另外 ...

  8. 懂点 Nginx 反向代理与负载均衡,是面试加分项没有之一

    点击上方"方志朋",选择"置顶公众号" 技术文章第一时间送达! 学到老活到老 前端圈一直很新,一直要不停的学习,而且在进入大厂的路上,还要求熟悉一门后台语言等等 ...

  9. Nginx反向代理多个应用时,通过BluePring使Flask支持二级路径(URL前缀)

    1. 预期 最近陆续基于Nginx,完成了三个应用的部署: 应用A:<在Ngnix上部署Flask应用> 应用B:<PaddleOCR加载chinese_ocr_db_crnn_mo ...

最新文章

  1. pat1011. World Cup Betting (20)
  2. python 守护线程 join_Python多线程threading join和守护线程setDeamon原理详解
  3. 保存mysql用户的登录信息到~.my.cnf文件;用于方便登录操作。
  4. 华为鸿蒙10月17日,华为宣布10月17日重磅新机:鸿蒙系统+全球首发屏下摄像头...
  5. Silverlight for Windows Phone 7开发系列(2):第一个Silverlight程序
  6. 基础知识巩固四(问题部分)
  7. P2611-[ZJOI2012]小蓝的好友【Treap,扫描线】
  8. 享受阅读的十二个好习惯
  9. 剑指Offer - 面试题60. n个骰子的点数(动态规划)
  10. Redis在游戏服务器中的应用
  11. SQL 数据定义语句(DDL)
  12. laypage分页java例子_总结laypage.js分页插件用法
  13. netty系列之:真正的平等–UDT中的Rendezvous
  14. [小知识] WPS恢复本地历史数据
  15. Spring漫画学习笔记(二) 什么是BeanFactory
  16. 【精品工具】几款好用的在线RGB、HEX颜色代码生成器
  17. 安卓bmi项目_bmi计算器
  18. Racket编程指南——21 运行和创建可执行文件
  19. CREO教程——1 初始配置
  20. Java 集合 --- String, StringBuilder, StringBuffer

热门文章

  1. M14-MongoDB索引原理及使用
  2. 你所不知道的经典期货技术分析
  3. Kali渗透之PING命令
  4. 电脑使用技巧提升篇6:清理C盘垃圾的3个方法
  5. html+css+js 下拉菜单
  6. openwrt添加新平台支持
  7. 右键收藏!2021 Google 开发者大会怎么看?
  8. 算法梳理boosting\bagging\RF(1)
  9. 工业机器视觉中光源的分类与选型
  10. android 6 root boot,震撼首发:一加6T解锁和获取ROOT权限教程