先后端分离:分离开发,一体发布

先后端分离开发实践了好久了,前两天须要把一个项目上线,准备 SSL 证书时发现,竟然须要申请 3 个证书(1 年期免费的证书只能对单个子域名申请),这 3 个域名是:html

  • sys.project.cn,Web 应用前端
  • api.project.cn,应用后端 RESTful API
  • m.project.cn,移动端

屁大点个项目,须要搞得这么复杂?用子路径不行吗?就像这样:前端

  • //sys.project.cn/
  • //sys.project.cn/api/
  • //sys.project.cn/m

回答我说,不行!由于是先后端分离方式开发的,每一项都是单独的项目,单独发布出来,只能分别做为网站发布……我那感受,就像喝了两瓶二锅头,不只醉了,并且上头,就差发酒疯了!node

且不说是否是必定要分离发布的问题,就算各自独立发布,至少有三种方案能够发布成子路径:web

  • 虚拟目录或纯静态的子目录
  • IIS 站点上“添加应用程序”
  • 使用 Nginx 反向代理

但这不是重点,重点是:数据库

分离开发就必定得分离发布吗

自从应用先后端分离开发模式以来,分工明确,合做愉快。最近后端通常是用 NET Core 开发,前端使用的 Vue 技术栈。若是偶尔后端人力不足,有点数据库基础的前端工程师还能够拿 Node.js 帮着实现一部分后端需求。移动端的 Android 团队已经精简得只剩下一我的了,只须要维护一个框架应用,处理点硬件调用,把移动端页面往里一套就能解决问题。npm

各团队已经习惯了分离开发,除了讨论接口设计,其余时候团队间交流最多的可能就是:“API 测试地址是啥,我须要联调一下。”因此各团队也习惯了本身发布,公布地址给其余团队测试、联调。长此以往,竟然造成了分离开发就得分离发布的印象。segmentfault

对于较大型一些的项目来讲,分离发布多是必要的:纯静态的前端部分能够发布到 CDN,后端部分能够发布到多个服务器上外加一层负载均衡。可是对于使用人数不过几百人,并发最多几十人的小型应用来讲,就一台应用服务器,把全部东西揉吧揉吧,放一块儿就能看成一体式开发的 Web 应用发布出来,真不必去分离。后端

就上面的例子来讲,除了应用后端须要跑程序,须要 NET Core Runtime,另外两项全是纯静态。然而,前端工程化

A: 另外两项不是静态的,由于要经过构建生成! B: 什么构建? A: Vue 框架写的,须要经过 npm run build 构建了才能发布。 B: 那么,构建结果是否是纯静态的? A: 构建结果应该不是纯静态的吧,须要在 IIS 上建站点发布。 B: 那么,构建结果直接用浏览器能够打开吗?不用 IIS,只用静态 http-server 能够部署吗? A: 好像能够 B: 那就是纯静态!

这是一个插曲,不过这得强调一下,“构建”这一过程的结果,不必定就非得是动态的 Web 应用。咱们已经在前端工程化上实践了这么久,应该了解:前端工程化以后,构建的结果是静态的,不须要在服务器上跑程序,只须要服务器按 URL 提供静态资源。api

分析下后端应用的发布内容

如今来看一下后端发布的结果(部分)

 .../api_publish
  |-- wwwroot/
  `-- *.dll

程序中,全部 API 都是经过路由中间件解析 URL 以后转发到各 Controller 的。假如发布后绑定了域名 api.project.cn,那么:

  • //api.project.cn/ 打开的是项目模板提供的一个默认页面,这个页面在 wwwroot 中 —— 对了,wwwroot 就是这个 Web 应用的静态资源目录
  • //api.project.cn/api/... 这个子路径下提供全套 Web API 服务

由于应用后端目前只提供 Web API 服务,wwwroot 里只不过放了一些没用的静态资源 —— 都是建立项目时模板提供的静态资源,彻底能够删得一个不剩。wwwroot 中的内容删干净以后,访问 http://api.project.cn/ 会获得一个 404,但不要紧,由于 API 无缺!

那么,若是把 wwwroot 里放上前端构建的结果呢?

看看前端项目结构

 .../project_root
  |-- src/   <-- 源文件
  |-- dist/   <-- 构建结构(发布目录)
  |   |-- index.html       <-- 入口页面
  |   |-- assets/         <-- 资源(图片等)
  |   `-- *.js;*.js.map   <-- 构建出来的 js 脚本等
  |-- node_modules/       <-- npm 包缓存
  `-- *       <-- 项目配置、说明等

这个结构中,dist 目录是 npm run build 构建出来的,这是一个发布目录,只有 dist 中的内容须要部署到 Web 服务器上。

揉一会儿

如今把 dist 目录放在后端发布目录 api_publish 中去,更名为 wwwroot,替换掉原来的 wwwroot,Api 的发布目录就变成了这样:

 .../publish
  |-- wwwroot/   <-- 前端构建结果:dist
  |   |-- index.html
  |   |-- assets/
  |   `-- *.js;*.js.map
  `-- *.dll

这个目录在 IIS 里部署出来,直接访问 //api.project.cn/(以前绑定的域名),咱们会毫无悬念地看到前端页面出来了。因为前端页面中 Ajax 调用的 Base URL 都是 //api.project.cn/,因此 API 调用也没有问题。

不过是 Web 应用的主页通常不会经过 //api.project.cn/ 来访问,因此绑定 sys.project.cn 域名来访问。//sys.project.cn/ 没有问题,能够打开页面。以前绑定的 api.project.cn 并未取消,因此 Ajax 调用也没有问题。

注:从 //sys.project.cn/ 经过 Ajax 调用 //api.project.cn/ 可能会存在跨域问题,不过在这个案例中,跨域问题早就处理过了,不细说。

申请 SSL 证书

接下来,开始申请 SSL 证书。若是只申请一个证书(收费证书很贵的),是该申请 api.project.cn 的,仍是 sys.project.cn 的?

无论 api.project.cn 仍是 sys.project.cn 均可能在接收到的请求中包含敏感信息,也可能在响应中包含敏感数据。别的不说,Ajax 调用就已经涉及到了两个部分的信息交换,任何一方不安全,总体都是不安全的。

可是只有一个证书,就得放弃一个域名,放弃哪个比较好?

sys.project.cn 是应用入口,应该告知用户,而 api.project.cn 是在页面中隐含调用的,因此应该放弃 api.project.cn。而放弃 api.project.cn,就意味着须要把 Web API 部署为 sys.project.cn 的子路径中,即 //sys.project.cn/api/。而后把前端 Ajax 调用的 Base URL 改成 //sys.project.cn/api/ 便可。

这不,//sys.project.cn///sys.project.cn/api 就把先后端揉合在一块儿了,搞成一体式发布。

再来个移动端

对了,还有一个针对移动端的前端静态资源须要发布,它和发布应用前端原理同样,可是得发布到 .../wwwroot/m/。问题是,须要以虚拟目录的形式发布吗?

其实这个问题不是难题,纯静态的东西,怎么揉都行。

一体式发布

若是,三端不是同时发布,而是各有各的生命周期,那最好发布成三个目录:

  • .../publish/api/,部署为 IIS 站点(删除掉其中的 wwwroot 目录)
  • .../publish/sys/,作成符号连接(Windows 下用 Junction)到 .../publish/api/wwwroot
  • .../publish/mobile/,能够直接在 IIS 中部署成 /m 虚拟目录,也能够 sys 那样作成一个符号连接

对于多数小项目来讲,三端都是同时发布、联合测试的。这种状况下,就可使用一个构建脚本将前端 dist 、移动端 dist 和 Web API 发布目录拷贝到一块儿,按以下结构发布:

 .../publish/
  |-- *.dll
  `-- wwwroot/         <-- 前端构建结果:dist
  |-- index.html
  |-- assets/
  |-- *.js;*.js.map
  `-- m/           <-- 移动端构建结果:dist
  |-- index.html
  |-- assets/
  `-- *.js;*.js.map

分离式开发

一体式发布说完了,再回过头来讲说分离式开发。

由于一开始的问题出如今部署的时候,因此咱们反推了一体式发布的过程。但实际上,应该反过来,按正常的顺序,从项目开始开发的时候来规划。

项目开始开发,说明它的需求已经肯定下来。那么,就基本上能肯定用户该怎么来使用它,它应该怎样部署。因此建立项目工做区的时候会想到这样一个目录结构:

 .../project
  |-- wwwroot/   <-- 前端静态资源
  |   `-- m/     <-- 移动端静态资源
  |-- **/*.cs     <-- 源代码
  `-- *           <-- 项目及其余各类配置文件等

而后进行分工计划:

  • 前端一组写 wwwroot,但要把 wwwroot/m 这个目录保留给二组
  • 前端二组写 wwwroot/m
  • 后端组写 project

若是直接在整个工做区中协做复杂度会比较高,并且前端工程师看到后端代码会头痛,后端工程师看到前端代码也头痛。因此拆分项目,同时决定构建方法:

  • wwwroot 建立一个前端项目 web,构建输出到 wwwroot
  • wwwroot/m 建立另外一个前端项目 mobile,构建输出到 wwwroot/m
  • project 从源文件中删除 wwwroot,不关心前端过程
  • 构建方法:按以下顺序总体构建

    • 构建 project,并总体发布到 .../publish/
    • 构建 web,获得 .../web/dist,将其拷贝到 .../project/wwwroot/
    • 构建 mobile,获得 .../mobile/dist,拷贝到 .../project/wwwroot/m/

而后各组领任务,项目技术负责人开始建立项目文件,编写开发规范……


边城客栈

请关注公众号边城客栈

看完了先别走,点个赞 ⇓ 啊,赞扬 ⇘ 就更好啦!

相关文章
相关标签/搜索