欢迎光临敏速云
我们一直在努力

深度学习之目标检测常用算法原理+实践精讲更上一层楼


本系列的前几篇文章主要关注前端。今天在这篇文章里,我们就来梳理一下低码海报平台服务器端的技术选择。团队能力,如果团队Node.js很有经验,也无所谓。如果不是特别熟的话,至少一个人应该可以涵盖。如果都没有,那就选最成熟最保守的一个去做。趋势,如果领导有一个很好的全局观,如果把以上两点融合起来,再加上趋势的补充,就非常好了。毕竟现在的技术创新太快了,如果你只是学,别人都不用,会很痛苦。

首先,我们这里的场景是rest api。其次,团队能力方面,大家对koa2和express比较熟悉。Koa2仍然由Express的原始团队构建,并致力于成为一个更小、更具表现力和更健壮的Web框架。在co和generator的帮助下,异步进程控制和异常捕获问题得到了很好的解决。其次,koa去掉了Express内置的路由器、view等功能,让框架本身变得更轻。综合以上因素,koa2是NodeJS框架的最终选择。数据库选择谈数据库不讨论数据结构就是耍流氓。先说结论:基本工作信息(不包括工作内容)更适合以表格形式存储,对应的是mysql。作品内容一般是JSON,比较适合存放在mongodb。在真实的在线环境中,肯定会出现高并发的场景。这时候缓存就很有必要了。redis在这里被用作缓存方案。至于为什么选择这个,下面我就分别简单介绍一下mysql,mongodb,redis。数据库是按照数据结构组织、存储和管理数据的仓库。每个数据库都有一个或多个不同的API,用于创建、访问、管理、搜索和复制保存的数据。我们也可以在文件中存储数据,但是在文件中读写数据的速度比较慢。关系型数据库俗话说:不懂MySQL的前端不是好前端。MySQL作为Web应用中关系数据库管理系统最好的应用软件之一,体积小,速度快,总拥有成本低,尤其是开源。一般选择MySQL作为中小型网站开发的网站数据库。MySQL是一个关系数据库管理系统。关系数据库的特点是:以数据表的形式。每个行为的各种记录名称每一列都是对应于记录名称的数据字段。许多行和列构成一个窗体。几个表格组成了数据库。可以看出,它是一种结构化的数据存储形式。结合我们的数据结构,用MySQL来存储作品的信息显然是合适的,因为我们需要清楚的知道每部作品的具体信息,同时也方便查询和展示。说完了MySQL,还得说说如何在node中连接MySQL。这里对应的ORM框架是Sequelize。简单来说,ORM就是通过实例对象的语法来完成关系数据库操作的技术,是“对象/关系映射”的简称。在节点开发中,通常使用ORM框架来简化直接的数据库操作,Sequelize是目前非常流行的ORM框架。这里有几个使用Sequelize添加、修改和检查的例子。查询单个用户const result = await user model . findone({其中:{id: id},});复制代码查询所有用户const result = await user model . findandcountall({订单:[[id , desc],//以相反的顺序],where: whereOpt,});复制代码创建新用户const result = await user model . create(data);复制代码更新用户信息const result = await user model . update(data,{其中:{用户名,},});复制代码MongodbMongoDB是一个基于分布式文件存储的数据库。用C++语言写的。旨在为WEB应用程序提供可扩展的高性能数据存储解决方案。MongoDB是介于关系型数据库和非关系型数据库之间的产物,是最丰富的,也是最像关系型数据库的。将数据存储为文档,数据结构由键-值(key=value)对组成。MongoDB文档类似于JSON对象。一个字段可以包含其他文档、数组和文档数组。看到这里,我不禁觉得工作数据非常适合存放在MongoDB中。其实我们并不太关心works的数据中JSON的具体信息,也没有数据字段关联。同样,MongoDB对应的ORM框架一般使用mongoose。Mongoose是nodejs提供的用来连接mongodb的库。类似于jquery和JS的关系,封装优化了mongodb的一些原生方法。简单来说,Mongoose就是MongoDB数据库操作在节点环境下的封装,一个对象模型(ODM)工具,将数据库中的数据转换成JavaScript对象,供我们的应用使用。与上面类似,下面是一些数据操作的例子:创作作品const new content = await workcontentmodel . create({组件,道具,设置,});复制代码根据工作ID查询工作内容const content = await workcontentmodel . find byid(contentId);复制代码更新指定ID的工作内容。await workcontentmodel . findbyidandupdate(contentId,{components:content . components [],props: content.props {},setting: content.setting {},});复制代码雷迪斯Redis是用ANSI C语言编写的开源键值存储数据库,符合BSD协议,支持网络、基于内存、分布式和可选持久化,并提供多种语言的API。Redis通常被称为数据结构服务器,因为值可以是字符串、散列、列表、集合和有序集合。Redis有许多优点,例如:

极高的性能–Redis可以每秒读取110,000次,每秒写入81,000次。丰富的数据类型——Redis支持二进制情况下的字符串、列表、散列、集合和有序集数据类型。原子性Redis的所有操作都是原子性的,也就是说,如果操作失败,要么成功执行,要么根本不执行。单个操作是原子性的。多操作也支持事务,即原子性,由MULTI和EXEC指令包装。丰富的特性——Redis还支持发布/订阅、通知、密钥过期和其他特性。结合其特点和优势,我们将选择它作为一些高并发场景下缓存的第一优先方案。当我们的作品上线时,我们会同时向Redis写一份作品资料。以后我们只会在每次更新工作数据的时候更新缓存。当用户访问works时,他们会优先访问缓存。如果无法读取缓存,访问请求将会命中数据库。登录验证目前,用户信息认证和授权常用的方法有两种——JWT和会话。我们来比较一下两种认证方式的优缺点。会议相关概念介绍Session::主要存储在服务器上,相对安全。Cookie:主要存储在客户端,不太安全。SessionStorage:仅在当前会话中有效,关闭页面或浏览器后清除。Localstorage:永久保存它,除非它被清除。操作原理客户端用用户名和密码访问/login接口,服务器收到后验证用户名和密码。如果验证正确,sessionId和session之间的映射关系将存储在服务器中。服务器返回响应,sessionId作为set-cookie植入客户端,因此sessionId存在于客户端中。当客户端发起非登录请求时,如果服务器给出一个set-cookie,浏览器将自动在请求头中添加该cookie。服务器接收请求,分解cookie,验证信息,验证成功后向客户端返回响应。优越性与JWT相比,最大的优势是你可以主动清除杂文。会话保存在服务器端,相对安全。结合cookie,灵活兼容(客户端和服务器都可以清零或加密)。处于不利地位的Cookie+session在跨域场景下表现不佳(不能跨域,是域变量,需要复杂的跨域处理)。如果是分布式部署,就需要让多台计算机共享会话机制(成本增加)。CSRF可以很容易地使用基于Cookie的机制查询会话信息可能有数据库查询操作。JWT相关概念介绍由于详细介绍JWT会占用很多文章,所以不是本文的重点。所以这里只是简单介绍一下。主要是和会话模式的比较。关于JWT的详细介绍,请参考token-tutorial.html 网。JW的原理是在服务器被认证后,生成一个JSON对象并发送给用户,如下所示:{【名称】:“森林”,「角色」:「瓦工」,“到期时间”:“2022年11月09日19: 09”}复制代码将来用户和服务器通信时,会返回这个JSON对象。服务器只依赖这个对象来验证用户的身份。为了防止用户篡改数据,服务器在生成这个对象时会添加一个签名。服务器不保存任何会话数据,也就是说,服务器变成了无状态,这样更容易实现扩展。jw的格式大致如下:这是一个很长的字符串,由一个点(.)中间。JWT的三个部分如下:标题(标题)有效载荷(有效载荷)签名(签名)复制代码与会话相比的JWT安全性(两者都有缺陷)RESTful API,JWT胜出是因为RESTful API提倡无状态,JWT符合要求。性能(各有利弊,因为JWT信息性强,所以体量也大。但是每次都需要服务器搜索会话,保存JWT信息,不需要再查询数据库)时效性,Session可以直接从服务器上销毁,JWT只有在时效性到了的时候才能销毁(更改密码无法防止篡夺者使用)jsonwebtoken因为RESTful API提倡无状态,而JWT正好满足了这个要求,所以我们采用JWT来实现用户信息的授权和认证。项目中使用了流行的jsonwebtoken。具体用法请参考。单元测试和接口测试在代码部署之前,进行一些单元测试是很有必要的,这样可以有效地、持续地保证代码质量。实践表明,高质量的单元测试也可以帮助我们改进自己的代码。Mocha一般是Nodejs最常用的测试框架不可或缺的。Mocha是一个丰富的Javascript测试框架,可以在Node.js和浏览器中运行。下面是介绍摩卡最常见的附加:函数add(a,b) {返回a+b;}复制代码如果你以前没有接触过单元测试,可以编写的测试用例如下:var sum = add(1,2);if (sum == 3) {Console.log(添加测试成功);}否则{Console.error(“附加测试中的错误”);}复制代码然后你需要写减法函数,乘法函数,除法函数,但是随着模块的增加,你会遇到一个问题。如果按照上面的代码模式,输出格式很乱,测试结果的统计也是缺失的。这个时候,著名的摩卡就要登场了。有了mocha,可以解决测试结果输出格式化和测试结果统计的需求。比如上面的加法测试用例,可以这样写:var assert = require( assert );描述(计算器,函数(){describe(#add(),function() {it( 1加2时应该得到3 ,function() {assert.equal(3,add(1,2));});});});复制代码这是摩卡最基本的用法。然而,单独使用摩卡是不够的。Node.js是一种用于后端开发的语言,后端开发实际上相当于编写HTTP接口为前端提供服务。然后Node.js的单元测试必须测试HTTP接口。如果按照摩卡的逻辑测试http接口:要求(“../server . js );var http = require( http );var assert = require( assert );it(should return hi cosen ,函数(done) {http . get( ,function(res) {RES . set encoding( utf8 );res.on(数据,函数(文本){assert.equal(res.statusCode,200);assert.equal(text, hi cosen );done();});});});复制代码如上面代码所示:访问接口,获取返回的数据,验证返回的结果。只需使用Node.js自带的http和assert模块值得注意的是,http.get访问http接口是一个异步操作。Mocha在测试异步代码时,需要为it函数添加一个回调函数done,并在断言结束时调用done,这样Mocha就可以知道何时结束这个测试。既然Node.js自带的模块可以测试HTTP接口,为什么还需要SuperTest呢?先看看下面的代码:var request = require( super test );var server = require(../server . js );var assert = require( assert );it(should return hi cosen ,函数(done) {请求(服务器).获取(/).预期(200).expect(函数(结果){assert.equal(res.text, hi cosen );}).结束(完成);});复制代码比较这两个测试代码,你会发现后者要简单得多。这背后的原因是SuperTest封装了发送HTTP请求的接口,并提供了一个简单的expect断言来确定接口是否返回结果。对于POST接口来说,使用SuperTest的优势会更加明显,因为使用Node.js的http模块发送POST请求非常麻烦。在这里,我从NodeJS框架选择、数据库选择、登录验证、单元测试、接口测试等方面阐述了我们服务器端选择的依据。在下一篇文章中,我将详细介绍服务器的整体架构设计以及不同模块之间的关系。


版权声明:本站大部分内容来自互联网,不拥有所有权,不承担相关法律责任。如发现有违法违规的内容或本文侵犯了你的权益, 请联系管理员,一经查实,本站将立刻删除。未经允许不得转载 » 深度学习之目标检测常用算法原理+实践精讲更上一层楼