其他概念
项目开发流程
需求分析、技术选型、系统设计、开发编码、调试测试、部署上线、运营推广等
需求分析
当我遇到某个问题、想到某个需求时,会 第一时间把它记录下来 ,但不是立刻就去做这个项目了。
记录的需求多了后,有时我会发现需求之间是可以有联系的,这个时候,我才会考虑是不是能把这些需求汇聚成一个新项目。还要再评估下时间和竞品:来不及、性价比不高、卷不过同行就不做。
举个例子:我之前背面试题的时候发现很多题目的题解是有问题的, 但是没有人去讨论和维护,于是我就先把这点记录下来;之后又发现大家有阅读整套面试题的需求,可以有个组卷功能,才有了之后的面试鸭(https://www.mianshiya.com)。
养成随时记录的习惯,自然酝酿出项目灵感,而不是等要做项目的时候再去硬想、硬分析,你会发现整个过程不仅轻松、而且最后做出来的项目会更实用、性价比更高。(我们做视频、写文章也是一样的)
技术选型
企业中的大项目,技术选型阶段要格外谨慎,不建议选择冷门、无人维护、无人熟悉的技术。但对于我们个人来说,不用考虑那么多,一般做项目时选择自己最熟悉的技术框架即可
- 前端用什么?一般就是在 Vue 和 React 间抉择,然后统一使用 Ant Design 这种 多框架兼容 的组件库,而不是一个项目用一个新的组件库。
- 后端用什么?一般是在 Java 和 Node 间抉择,小项目、侧重前端的项目用 Node(比如 yuindex:https://github.com/liyupi/yuindex),追求稳定性的大项目用 Java SpringBoot。
- 怎么上线?一般前端用 Nginx、后端用 Docker
- 尽量有一套自己用的最熟的技术栈,大多数项目都不用纠结技术选型。也别非得追求什么都用过,结果用的都不熟。
系统设计
- 关于系统设计,我觉得最重要的还是积累经验,很多需求和业务场景其实都是通用的(比如用户鉴权),只要你设计过一次,之后做类似的系统应该都是无压力。
- 在做系统设计的过程中,建议大家绘制一些图来辅助理解,比如流程图、时序图、功能模块图等等,用在线绘图工具 draw.io 即可。
开发
当然,你也可以直接到 GitHub 上找一个开源项目去二改,比如知名的后台管理系统 Vue Admin Template。站在巨人的肩膀上,能帮助你大幅节省代码量和开发时间,屡试不爽。
- 能不自己写的代码,就不要自己写
- 自己写过的代码,绝对不重复写第二遍
- 果是新项目,我会选择一个最符合我需求的脚手架来创建初始化项目模板,比如前端的 Ant Design Pro,什么布局、导航、路由、菜单、主题、整合组件、请求、测试、权限管理、国际化全都给你整合好了
- 项目一定要有计划!
- 今天做什么、明天做什么、每个功能花多少时间等,分清主次,先完成核心功能、再去完善细节。而不是功能还没开发完,就搁那纠结前端界面、什么字体大一号小一号的,到时候如果都上不了线,你觉得纠结这些事情还有意义么?
测试
- 单元测试到底是什么玩意?
部署
像我自己一般是使用 Vercel 免费的国外服务器来一键上线前端项目(还有个好处是不用备案);用腾讯云托管之类的容器平台来快速发布用 Docker 打包的后端代码。或者就是用宝塔面板来可视化地运行 Node、PHP、Java 等项目,可比自己登上服务器,手动启动停止项目要方便多了。
至于微服务项目嘛,也可以用同样的方式来部署,或者用 Docker Compose 来编排群起微服务。不过真正要上线一个产品,在没有用户的时候,我是不会选择用微服务的。
运维
- 一般我不会选择自己搭建运维监控管理平台,而是直接用现成的第三方服务。比如用百度统计、51.LA 来统计网站用户,用现成的第三方云数据库、云 Redis、容器托管平台来监控服务的运行、配置告警等等
- 换句话说,想要真正做到快速,有现成的服务就用现成的吧,虽然会花一些额外的金钱投入,但是能省下来大量时间,性价比绝对是高的。对企业来说,时间就是金钱。
实际工作步骤
- 根据需求设计前端界面
- 设计接口文档
- 建立数据库表、搭建基本环境
- 前后端分离开发
- 联调
- 上线
接口设计
- 接口设计六大原则
- 单一职责原则(Single Responsibility Principle);
- 开闭原则(Open Closed Principle);
- 里氏替换原则(Liskov Substitution Principle);
- 迪米特法则(Law of Demeter),又叫“最少知道法则”;
- 接口隔离原则(Interface Segregation Principle);
- 依赖倒置原则(Dependence Inversion Principle)。
概念
同步|异步
- 同步 sync:按顺序执行,前面的内容执行结束后,才会执行后面的部分
- 例:js 代码阻塞运行
- 异步:不需要等待某一部分执行,可以同时执行
- 例:有回调函数(事件、定时器)、Ajax
框架与库
框架(framework):
框架规定了自己的编程方式,是一套完整的解决方案,
大部分的逻辑在框架内部已经被确定,
使用时:需要根据规则填充自己的内容,具有一定的限制,但很强大(类似完形填空)
- 例子:Vue.js
库(Library):
提供了一系列方法的集合,可以调用方法且程序逻辑由自己掌握,而并不是在库中定好的。
本质:一些函数的集合,每次调用函数实现一个特定的功能,只是一个工具
使用时:更自由,可以随意调用或不调用
- 例子:jQuery
数据代理
概念:通过一个对象代理对另一个对象中属性的操作(读/写)
// vue2: 借助Object.defineProperty为对象追加属性 let obj = { x:100 } let obj2 = { y:200 } //通过obj2中的x对obj中的x进行读写操作 Object.defineProperty( obj2,'x'{ get(){ return obj.x }, set(value){ obj.x = value } })
防抖节流
为了限制 JS 频繁的执行一段代码
例:scroll 事件,只是轻微滚动一下滚动条就触发多次事件,由于过于频繁地 DOM 操作和资源加载,严重影响了网页性能,甚至会造成浏览器崩溃
此时:用 debounce(防抖)和 throttle(节流)的方式来减少调用频率,同时又不影响实际效果
防抖:
- 连续的多次触发,固定的时间间隔内,存在新的触发,就清除之前的重新记时,满足时间执行一次——最新一次触发(只保留 新事件)
- 手段 1:通过设置 setTimeout 定时器的方式延迟执行,当快速多次点击的时候,每一次都会重置定时器,只有你一段时间都不点击时定时器才能到达条件并执行事件函数。即如果触发事件后在 n 秒内又触发了事件,则会重新计算函数延执行时间。
- 模拟一个表单提交的例子,多次快速点击提交后只会执行一次
节流(节流阀):
连续的多次触发,每一段固定的时间间隔内,我们只去执行一次——固定频率触发(忽略新产生的同类事件)
确保某个事件,在同一时间只能有一个
如果已经存在,就保留原来的,不再触发
与防抖最大的区别就是,无论事件触发多么频繁,都可以保证在规定时间内可以执行一次执行函数
例:用户在滚动页面时,每隔一段时间发一次 ajax 请求,而不是在用户停下滚动页面操作时才去请求数据
js 锁机制
JavaScript 可以通过 resolve/reject 函数来实现锁,在没有调用 resolve/reject 函数时,promise 会看起来相当于一直阻塞(其实和 Java 的阻塞不一样,这里只是没有执行后续的函数)。
// 示例
`<body>
<input onclick="clickMe()" type="button" value="点我">
</body>`;
async function clickMe() {
const env = await getEnv();
console.log(env);
}
let localEnv, p;
const queue = [];
let loading = false;
async function getEnv() {
return new Promise((resolve, reject) => {
if (localEnv) {
resolve(localEnv);
}
// 进入这个if的Promise没有调用resolve(),会一直阻塞
if (loading) {
// 把resolve存入数组,待请求返回后执行resolve
queue.push({ resolve, reject });
}
if (!loading && !localEnv) {
loading = true;
console.log("questing env......");
setTimeout(() => {
localEnv = {
platform: "141001",
appid: "aoshdakhpa8fkdng",
};
loading = false;
resolve(localEnv);
// 异步请求结束,调用所有正在阻塞的Promise的resolve函数,返回结果,解除阻塞
while ((p = queue.shift())) {
p.resolve(localEnv);
}
}, 2000);
}
});
}
重排(回流)、重绘
DOM 性能 浏览器的性能大部分都是被这两个问题所消耗
- 重绘不一定需要回流(比如颜色的改变),回流必然导致重绘(比如改变网页位置)
- 重绘:元素中的背景、透明度、颜色发生变化后,浏览器针对某一元素进行单独的渲染
- 重排(回流/重构):DOM 位置、大小或结构、定位发生变化;导致浏览器重新渲染整个 DOM 树、非常耗性能
- 添加、删除可见的 dom
- 元素的位置改变
- 元素的尺寸改变(外边距、内边距、边框厚度、宽高、等几何属性)
- 页面渲染初始化
- 浏览器窗口尺寸改变
- 获取某些属性:offsetTop、offsetLeft、 offsetWidth、offsetHeight、scrollTop、scrollLeft、scrollWidth、scrollHeight、clientTop、clientLeft、clientWidth、clientHeight、getComputedStyle() (currentStyle in IE)。在多次使用这些值时应进行缓存
- 优化:
- 不要一条一条地修改 DOM 的样式,可以先定义好 css 的 class,然后修改 DOM 的 className
- 不要把 DOM 结点的属性值放在一个循环里当成循环里的变量
- 获取浏览器重排 DOM 节点的属性值,存储到变量中
- 避免使用 table 布局,很小的改动会造成整个 table 的重新布局
微任务/宏任务
- JavaScript 中分为同步任务和异步任务,而异步任务中又分为宏任务和微任务两种;先执行同步任务,再执行异步任务;
- 微任务永远比宏任务先执行;同层级先微任务后宏任务的顺序
- 在执行微任务过程中产生的新的微任务并不会推迟到下个宏任务中执行,而是在当前的宏任务中继续执行。
- 微任务:Promise 相关任务,Mutation Observer 等等
- 宏任务:定时器,用户交互事件等
SPA 单页应用
单页面应用指:只有一个 web 页面的应用。
- 特点:浏览器一开始直接加载必须的 HTML、CSS、JS,所有的操作都在这一个页面上完成,有 JavaScript 控制交互和局部刷新
- 优点:
- 有利于前后端分离
- 良好的用户体验,不刷新界面,显示更流畅
- 减轻服务器压力,不需要频繁请求界面
- 缺点:
- 初次加载比较耗时
- 不利于 SEO 优化
内存泄露与内存溢出![cc7e479d79011785c4840cad18c1131](C:\Users\86138\AppData\Local\Temp\WeChat Files\cc7e479d79011785c4840cad18c1131.png)
![6d8e985e74b1995b56e6ff97029dc9d](C:\Users\86138\AppData\Local\Temp\WeChat Files\6d8e985e74b1995b56e6ff97029dc9d.png)
事件委托
- addEventListener 事件绑定第三个参数默认为 false 事件冒泡阶段
- 优点:
- 提高性能:每个函数都会占用内存空间,只添加一个事件处理程序,所占用的内存空间更少
- 动态监听:使用委托可监听“未来”的元素
原生事件机制
- 到目前为止,一共出现多少种事件机制?
- 一共存在 3 种
- 事件捕获机制
- 事件冒泡机制
- 标准事件机制
- 标准事件机制,一共分为几个阶段?
- 捕获阶段
- 从最外层的 document 元素开始向内逐层传递,触发同类型事件,直到找到目标元素为止
- 目标阶段
- 捕获阶段结束之后,将目标元素身上所有的同类型事件全部触发
- 冒泡阶段
- 目标阶段结束之后,从目标元素开始向外逐层传递,触发同类型事件,直到最外层 document 元素为止
- 捕获阶段
- 如何绑定事件监听?
- 举例:现在需要给 div 节点,绑定 click 事件监听
- div.onclick=function(){}
- 本质:是对 div 对象的 onclick 属性进行赋值
- 该方法对于每个节点的每个事件,都只能绑定一个回调函数,后绑定的会覆盖之前绑定的
- 该方法只能绑定冒泡事件
- div.addEventListener('click',function(){})
- 本质:是调用 div 对象身上的 addEventListener 方法,并传入事件回调函数
- 该方法对于每个节点的每个事件,都可以绑定多个回调函数
- 第三个实参:
- 数据类型:
- 布尔值
- true->将当前事件存放于捕获阶段触发
- false->将当前事件存放于冒泡阶段触发
- 对象
- capture 属性
- true->将当前事件存放于捕获阶段触发
- false->将当前事件存放于冒泡阶段触发
- passive 属性
- 前言:部分浏览器存在调用 event.preventDefault()方法默认无效的情况
- true->事件回调函数中的 event.preventDefault()方法生效
- false->事件回调函数中的 event.preventDefault()方法不生效
- capture 属性
- 布尔值
- 数据类型:
- 如何阻止事件冒泡?
- event.stopPropagation();
- event.cancelBubble=true;
- 扩展:如何阻止事件捕获?
- event.stopPropagation 方法在冒泡阶段事件中使用,就是阻止冒泡,捕获阶段事件中使用就是阻止捕获
- 问题:请问我们绑定的是事件还是事件的回调函数?
- 简单说法:给 div 绑定 click 事件
- 完整说法:给 div 绑定 click 事件的回调函数
- 绑定的是事件的回调函数,不是事件,每个标签具有什么事件都是由 W3C 规范制定的,不是我们绑定的
常识
软链接
软链接:相当于快捷方式,不占用内存空间
- https://www.jianshu.com/p/b035d94fa959
硬链接
相当于复制一份文件,但文件内容是同步的,
端口
- 端口范围:0~65535
- 知名端口:0~1024
- 常见端口:80、Mysql3306、mongodb27017
加密
- md5 加密
- JSEncrypt 加密解密
设计模式
- 定义:在面向对象软件设计过程中针对特定问题的简洁而优雅的解决方案
- 作用:在于可复用性、可维护性。
- 原则:找出程序中变化的部分,并将变化封装起来。
- 设计模式会增加代码量,容易将逻辑混论
- 但软件的开发成本,不仅在开发阶段,也在后期维护阶段,采用好的设计模式,有利于降低维护成本
- 设计模式分为两部分:
- 可变:
- 不可变:将可变的部分封装后,剩下的就是不变和稳定的部分
- 设计模式的误解:
- 设计模式的滥用,导致不该使用的地方使用,适得其反
- 模式应该用在正确的地方
- 关注模式的意图而不是结构,模式只用放在具体的环境才有意义
误解
不同语言的语法特性是不一样的,准确的说,最初的 23 种设计模式是针对 cpp、java 等静态类型、传统面向对象编程语言设计的,而在 JS 中有些模式可能已 经不再需要,而有些模式的实现会有变化。比如有些人为了实现 JS 版的工厂模式,生硬的将创建对象的步骤延迟到子类中,实际上在静态类 型语言中让子类来“决定”创建对象的原因是为了迎合“依赖倒置”原则,解开对象类型的耦合,让对象表现出多态性,而在 JS 这种动态类型语言中,多态是天生的, JS 不存在类型耦合,不需要将对象延迟到子类中创建,所以 JS 其实是不需要工厂模式的。
应用设计模式是为了解决问题,像上述这种牵强的应用只会让人觉得设计模式既难懂又没什么用,影响设计模式在 JS 中的发展。
模式的发展
设计模式在 1995 年最初被提出时有 23 种,但它不应该被局限于这 23 种,从它被发明到现在这些年也许已经有更多的模式被发现并总结了出来,比如有些 JS 书籍会提到模块模式、沙箱模式,这些模式能否经受住时间考验还有待验证,但设计模式是在发展的,不仅限于最初的 23 种。
行为型模式
行为型设计模式通常用来解耦
它是对在不同的对象之间划分责任
和算法
的抽象化,行为型模式不仅仅关注类和对象的结构,而且重点关注它们之间的相互作用;行为型模式一共有以下 11 种
- 模板方法模式(Template Method)
- 策略模式(Strategy)
- 命令模式(Command)
- 中介者模式(Mediator)
- 观察者模式(Observer)
- 迭代器模式(Iteratior)
- 访问者模式(Visiter)
- 责任链模式(Chain of Responsibility)
- 备忘录模式(Memento)
- 状态模式(State)
- 解释器模式(Interpreter)
策略模式
针对一组算法,将每一个算法封装到具有共同接口的独立的类中,使得它们可以互换。
观察者模式
定义:观察者模式定义了对象间的一种
一对多
的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知,并自动更新。观察者模式属于行为型模式。
理解:一个目标对象对应多个观察者,当目标对象发生改变时,就通知所由的观察者
步骤
- 在目标对象中维护了一个观察者的数组,新增时将观察者向数组中 push;
- 然后通过 notify 通知所有的观察者;
- 每个观察者只有一个 update 函数,用来接收观察者更新后的一个回调;
观察者模式把观察者对象维护在目标对象中的,需要发布消息时直接发消息给观察者。在观察者模式中,目标对象本身是知道观察者存在的
// 定义一个目标对象 class Subject { constructor() { this.Observers = []; } add(observer) { //添加 this.Observers.push(observer); } remove(observer) { //移除 this.Observers.filter((item) => item === observer); } notify() { //通知所有观察者 this.Observers.forEach((item) => { item.update(); }); } } //定义观察者对象 class Observer { constructor(name) { this.name = name; } update() { console.log(`my name is:${this.name}`); } } let sub = new Subject(); let obs1 = new Observer("observer11"); let obs2 = new Observer("observer22"); sub.add(obs1); // 添加到观察者队列 sub.add(obs2); sub.notify(); // 触发所有的观察者
设计模式
订阅发布模式
发布订阅模式是基于一个事件(主题)通道,希望接收通知的对象
Subscriber
通过自定义事件订阅主题,被激活事件的对象Publisher
通过发布主题事件的方式通知各个订阅该主题的Subscriber
对象。
- 与观察者模式的不同:增加了第三方即
事件中心
;目标对象状态的改变并非直接通知观察者,而是通过第三方的事件中心来派发通知。 - 订阅者订阅主题,发布者推送某个主题时,订阅该主题的所有读者都会被通知到;避免了观察者模式无法进行过滤筛选的缺陷。
- 而发布/订阅模式中,发布者并不维护订阅者,也不知道订阅者的存在,所以也不会直接通知订阅者,而是通知调度中心,由调度中心
(公用的对象实例)
通知订阅者。 - 例:
- Vue2 中的模板语法,实现数据与界面的双向绑定,数据与页面相互更新
单例模式
单例就是保证一个类只有一个实例,并提供一个访问它的全局访问点
- 实现方法
- 一般是先判断实例存在与否,如果存在直接返回,
- 如果不存在就创建了再返回,这就确保了一个类只有一个实例对象。
- 在 JavaScript 里,单例作为一个命名空间提供者,从全局命名空间里提供一个唯一的访问点来访问该对象
- 使用场景
- 团队开发中,可能会产生命名冲突,这时候单例模式就能很好的解决这个问题。
- 全局模态框,同一时间只允许弹出一个模态框,内容可以不一样,但都是同一个框,elementUI
代理模式
为一个对象提供一个代用品或者占位符,以便控制对它的访问
- 常用虚拟代理形式:某一个花销很大的操作,可以使用虚拟代理的方式延迟到需要它的时候再去创建它,(虚拟代理实现图片懒加载)
- 图片懒加载方式,使用 loading 图占位,然后通过异步的方式加载图片,等图片记载好了再替换掉
中介者模式
- 通过抽离配置项,进行代码的控制,实现各个事件的解耦,仅仅维护好中介者就行了
装饰器模式
- 不改变原对象的基础上,在程序运行时给对象动态的添加方法。
云服务器使用:
服务器管理软件:宝塔、LNMP、海外版(aapanel)、1Panel
- 在终端中输入连接命令
ssh root@111.67.199.222
(公网 ip) - 使用 linux 命令 / vim 命令 操作系统
1Panel - 现代化开源 Linux 服务器运维面板
- 安装:在线安装 - 1Panel 文档
- .... 更多支持可通过首页联系方式找我帮助!
宝塔面板
常用软件:
- pm2 node 包管理器
- mysql
# ubuntu 中安装宝塔面板 wget -O install.sh http://download.bt.cn/install/install-ubuntu_6.0.sh && sudo bash install.sh
安装:
yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh
查看公网登录地址
bt default
- 外网面板地址: http://8.142.208.202:8888/a3e99629 内网面板地址: http://172.18.218.46:8888/a3e99629
ssh 登录报错
- 原因:第一次 SSH 连接时,生成的认证储存在客户端(也就是用 SSH 连线其他电脑的那个,自己操作的那个)中的 known_hosts,
- 但是如果服务器验证过了,认证资讯当然也会更改,服务器端与客户端不同时,就会跳出错误
- 因此,只要把电脑中的认证资讯删除,连线时重新生成,就一切完美啦~要删除很简单,
- 只要在客户端输入一个指令
ssh-keygen -R 服务器ip地址
PS C:\Users\wzt> ssh root@8.142.208.202
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ED25519 key sent by the remote host is
SHA256:/y9BDVH04wKb/ouMYigQuyAuyn5yCnxLAQ/S6xMpTB8.
Please contact your system administrator.
Add correct host key in C:\\Users\\wzt/.ssh/known_hosts to get rid of this message.
Offending ECDSA key in C:\\Users\\wzt/.ssh/known_hosts:3
Host key for 8.142.208.202 has changed and you have requested strict checking.
Host key verification failed.
开放服务器端口
- 配置安全组规则,打开对应端口,否则无法使用
- 远程连接实例所需的 22、3389 端口在创建安全组时默认为开启状态
- 您需要确认安全组的入方向已开放这些端口。如果未开放,请手动配置
- mysql 数据库端口:3306
断开 ssh 连接后继续运行程序
- 使用 screen 运行
- 安装命令执行任务 CentOS
yum install screen
- 创建 screen 窗口
screen -S name
//name 用于标注 screen 窗口的用途,自由命名 - 执行 screen -S name 之后系统会跳进一个新窗口,我们创建的新进程来执行
- 在这里面启动程序即可
- 离开 screen 窗口并保留程序在后台运行
ctrl + a + d
- 查看 screen 进程
screen -ls
- 进入进程
- 仅有一个进程时:
screen -r -d
- 当有多个进程:
screen -r -d pid
//pid 是进程的编号
- 仅有一个进程时:
- 在窗口中
ctrl + a
再按下 d 键,就可以退出 ssh 登录,实现后台运行! - 删除进程
screen -S PID -X quit
//PID 是进程号
- 安装命令执行任务 CentOS
- 使用 nohup 执行
- 使用管理终端执行
本地与服务器的文件传输
- linux 的根目录
/
- 管理员用户的位置
/root
相当于~
使用 scp 命令
- 需要提供服务服务器的开机密码
本机--服务器
- 把本机的文件传给目标服务器
scp 本机文件路径 root@192.168.1.147:服务器目标路径
//ip 地址为目标服务器地址
- 把本机的文件夹传给目标服务器
scp -r 本机文件夹路径 root@192.168.1.145:服务器目标路径
服务器---本机
- 把远端服务器文件拷贝到本地
scp root@192.168.1.147:服务器的文件路径 本地文件存放路径
//ip 地址为目标服务器地址
基础环境
配置
node.js
环境- 使用二进制文件安装。
- 下载文件
wget https://nodejs.org/dist/v6.9.5/node-v6.9.5-linux-x64.tar.xz
- 解压之后,在 bin 文件夹中就已存在 node 和 npm,无需重复编译。
- 解压文件
tar xvf node-v6.9.5-linux-x64.tar.xz
- 创建软链接,您就可以在任意目录下直接使用 node 和 npm 命令。
ln -s /root/node-v6.9.5-linux-x64/bin/node /usr/local/bin/node ln -s /root/node-v6.9.5-linux-x64/bin/npm /usr/local/bin/npm
安装 git 工具
yum -y install git
安装 git
安装 mysql
- 具体步骤看阿里云服务器官网
安装 MongoDB 数据库(教程:Linux 系统安装 MongoDB 数据库)
- 从官网下载安装包 并上传到服务器
tar -zxvf mongodb-linux-x86_64-rhel70-5.0.4.tgz
对压缩包进行解压- 将解压后的文件移动到指定目录下
mv mongodb-linux-x86_64-rhel70-5.0.4 /usr/local/mongodb5
- MongoDB 的可执行文件位于 bin 目录下,所以可以将其添加到 环境变量PATH路径中:
export PATH=/usr/local/mongodb5/bin:$PATH
,其中/usr/local/mongodb5/bin
表示 mongodb 可执行文件的绝对路径。 - 执行
mongo --version
命令查看 mongodb 版本如果成功表示配置成功。 - 创建配置文件
- 创建数据库文件夹,在 mongodb 的安装目录下创建
data/db
文件夹,这里/usr/local/mongodb5
就是我系统上的安装目录。 - 创建日志文件,在 mongodb 的安装目录下创建
logs
文件夹。 - 创建配置文件夹,在 mongodb 的安装目录下创建
etc
文件。 - 创建配置文件,在上一步创建的
etc
目录下使用vi mongodb.conf
命令创建配置文件,并且写入如下内容
- 创建数据库文件夹,在 mongodb 的安装目录下创建
# 数据存储路径 dbpath=/usr/local/mongodb5/data/db # 日志文件路径 logpath=/usr/local/mongodb5/logs/mongodb.log # 端口号 port=27017 fork=true journal=false storageEngine=wiredTiger
启动 mongodb
- cd 到 mongodb 目录下的 bin 文件夹,执行如下命令:
./mongod --config /usr/local/mongodb5/etc/mongodb.conf
- 启动后,在任意目录下输入
mongo
命令就可以使用 mongodb 数据库了。
- cd 到 mongodb 目录下的 bin 文件夹,执行如下命令:
其他问题
Apache 重定向配置
[apache 服务器配置,H5 路由刷新问题](https://blog.csdn.net/xuxiaoping1989/article/details/84071458#:~:text=刷新页面时访问的资源在服务端找不到,因为react-router设置的路径不是真实存在的路径。 如上的 404 现象,是因为在 apache 配置的根目录下面压根没有 userinfo 这个真实资源存在,这些访问资源都是在 js 里渲染的。 三、解决方案,1:进入 apache 目录的 conf 目录 2:打开 httpd.conf 3:找到%23LoadModule rewrite_module modules%2Fmod_rewrite.so 然后把前面的%23 去掉 4:找到所有的 AllowOverride 配置项,把所有的 None 都修改为 All)
<!-- 1.在网站根目录下面新建一个 .htaccess 文件,写入: -->
<IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteRule ^index\.html$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.html [L] </IfModule>
<!--
2.进入apache目录的conf目录 \ 打开httpd.conf
找到 #LoadModule rewrite_module modules/mod_rewrite.so 去掉前面的#
找到所有的AllowOverride配置项,把所有的None都修改为All
-->
<!-- 3. 重载apache配置 -->
关于 CDN
域名解析指向 -> CDN 解析指向 -> 真实服务器+端口 -> 根据本地代理等指向真实文件
域名解析、cdn 解析、本地服务搭建;三个节点都可以进行 ssl 加密证书的部署
HbuilderX 网页打包原生 app
- 新建 web app 项目
- 进行配置
- 云打包
- over