多域名应用的心思是从 WordPress.com 的时候起来的,当时一直在想,如何实现这种多域名的应用?
最近看到了一个实现,算是解了心头的疑惑。
如果不涉及 SSL ,子域名应用的实现并不算复杂,可以简单的通过将用户请求进行 rewirte 转发的方式,来实现对请求的转发。
举个例子,比如将 x.example.com
转发到 www.example.com/pages/x
中,这样在应用中就无需单独对于多域名编写代码,只需要从 Path 中提取前缀,并进行数据库查询,将数据结果返回回去就好。
如果涉及到 SSL,子域名应用的实现相对复杂一些,涉及到了 SSL 证书的管理。不过也有实现简单的方式,那就是购买一个泛域名证书,这样 Nginx 会通过泛域名证书提供服务,因此,应用程序在处理上和上面的逻辑一样,只要将请求转发就好了。
如果涉及到子域名绑定,则相对麻烦一些,需要能够编程式的操作 Nginx 的代码文件,不过也还好,你可以在应用的目录下动态的生成 Nginx 的配置文件,并在默认的配置文件中 include
动态生成的目录,从而避免文件生成后的管理成本太高。此外,需要借助 execl ,执行命令对 Nginx 执行检查和重启的操作。
此外,也可以考虑直接使用 default_server
,从而直接将所有未识别的情况转发到某个特定的路径。不过需要在应用中添加请求判断,对于无法绑定的域名,提供一个特定的反馈,引导用户进行绑定。
总结
如果你的应用不涉及到 SSL,也不涉及到域名绑定,则十分简单,直接使用 Nginx 转发请求即可;但如果涉及到了 SSL,则需要考虑泛域名证书,从而降低编程的成本;如果涉及到了域名绑定,则需要为应用程序新增对 Nginx 操作的能力,从而降低应用的管理和研发成本。
在和狗叔(@googollee) 沟通了一下得知,除了上述更为静态的方案以外,还有一些更加动态的方案,包括:
- 使用 openResty + MySQL DB ,实现根据
server_name
返回不同的 SSL 证书和信息,自动完成路由转发。 - 使用 Envoy Proxy:envoy proxy 提供了 dynamic configuration api,在 API 中返回相应的配置,实现功能。
- 使用 Haproxy
nginx 好像可以用正则或者通配符识别 server_name,然后 rewrite 一下或者 return 302应该就好了吧?(我也没有试过
是的,通配符是必然会用到的。文章中提到的涉及到 Nginx 转发的部分,基本上都是使用通配符识别来实现的。
补充的更动态的部分主要是解决多域名绑定且提供 SSL 证书的场景。希望可以通过 DB 存储域名 & 证书,在 Proxy 层直接返回结果。