作为一个后端,就最近公司项目部署过程中遇到的一点问题,与大家探讨一下。
由于开发和部署都完全采用前后端分离的方式,前端调用后端API,通常需要指定一个后端网关的Host
,不同环境的后端网关,Host
肯定是不一样的。
目前采用的方式:前端用node作为静态文件服务器,输出index.html
和需要的脚本,同时读取环境变量,在index.html
中插入一段脚本,定义一个HOST_ADDR
的全局变量。也可以在index.html
插入一个特殊路径的脚本,node捕获这个请求并输出,总之是通过全局变量的方式解决。
前端同事觉得很难受,倾向于以下2个解决方式:
- 针对不同环境打不同的镜像,将
HOST
写在前端config
文件,并打入最终镜像里。 - 前端部署到生产环境时,只请求同域名下的一个
/api
路径,采用反向代理的方式,将这些请求重定向到真正的后端网关。
这两种方式,我个人认为有以下不足:
- 就我从事服务化设计和开发的经验来看,代码与配置分离,是最佳实践。当一个镜像在测试环境测试通过,可以直接部署到生产环境,而不是换一个
env
再打一个镜像;由于采用条件编译,很难说有没有代码上的变更。 - 多增加一层代理,产生了额外的网络开销。同时后端服务的高可用受到前端代理的影响。
请大家分享下自己的实践经验,给点高见!
我觉得目前的方式就很好啊,不过不用node,直接nginx也可以办到 第一种方式,可以这样,在前端的文件里,有不同环境的config文件,然后不同环境的nginx配置返回不同的的config文件这样
关于这个,我认为是 代码里面读取环境变量 HOST,在配置中设置环境变量
比如在 PM2
或 Docker Compose
的配置中设置环境变量,指定 HOST.
最好的当然是用 Nginx 做反向代理, 多增加的那层代理开销不算什么,都是内网传输,速度很快
而且前端自己也可以做负载均衡 (如果是服务端渲染的话), 还可以消除跨域
@yuu2lee4 不同config文件,本质上还是把配置打到了镜像中,我个人觉得还是有缺陷。比如:新增加一套环境,就得重新编译一套镜像。
而且nginx仍然要读取环境变量,用于确定当前运行于什么环境,那么也就可以直接将HOST配置到环境变量并输出了。
@axetroy “代码里面读取环境变量 HOST,在配置中设置环境变量”,这一点上我和你的观点是相同的。
作为一个纯后端,我可能对前端在前后交互上的角色有点误解。我一直的观点是前端只输出HTML等静态资源,对后端接口的调用是通过直接请求的方式。另外我们目前的架构上,后端网关已经做了反向代理+负载均衡,不同的客户端(网站,mobile)应该是直接访问它。网站对应的后端API,也是作为一个后台服务隐藏在网关之后。
关于nginx做前端代理,如果忽略调用链上的损耗,还得考虑高可用问题。后端网关是冗余的方式保证高可用,如果每个前端项目也采用这种部署方式,运维很吃力,资源上也是一笔开销。
我还考虑过针对每个前端项目构建一个BFF层。也是考虑到高可用,没有进一步深入。
… 你想要动态配置就上 etcd 和 zookeper ,再说了,网关一般唯一。网关就像一个门一样,可出可进,在微服务里面最主要用来派发服务。你一个前端请求好几个网关是什么哦,不能有一个总的吗?
一般 K8s 的话都会有 Ingress ,没上 k8s 你就自己动手写一个服务中心吧,架构跟自动化,这方面 Go 比较合适,比如这个 https://github.com/spf13/viper。
可以参考 java 的技术栈 http://www.cnblogs.com/java-zhao/p/6716059.html
@MiYogurt 不同环境不同网关哈,测试环境和生产环境从网络上都是隔离的,有不同的网关很正常啊.