从App业务逻辑中提炼API接口
2.1 从App业务逻辑中提炼API接口
业务逻辑思维导图
功能-业务逻辑思维导图
基本功能模块关系
功能模块接口UML(设计出API)
在设计稿标注API
编写API文档
2.2 设计API的要点
根据对象设计API
API的命名
API的安全性
API所返回的数据:禁止返回Null值
图片的处理:图片数据库保存原图,在App客户端本地缓存图片不存在时,按图片尺寸向服务端请求动态生成。
返回的提示信息:给用户看的提示和给程序员看的提示。
在线API测试文档:使用Swagger-UI搭建,按TDD(测试驱动开发)原则进行开发。
在App客户端启动时调用一个API获取必要的初始化信息:比如App版本
关于API的版本升级问题:V2版本的API的Controller必须要继承V1版本的Controller,V2版本的API只重写需要改动的API。
2.3 如何选择合适的数据库产品
2.3.1 Redis、MongoDB、MySQL读写数据的区别
Redis的数据是存放在服务器的内存,当内存用满了后需要扩容,就只能使用Redis的分布式方案。为了防止断电或Redis程序重启造成内容数据的丢失,可调整Redis配置文件,按照一定的策略把数据持久化传到硬盘。
MongoDB同时使用了硬盘和内存,其使用了操作系统提供的MMAP(内存文件映射)机制进行数据文件的读写,MMAP可以把文件直接映射到进程的内存空间中,这样文件就会在内存中有对应的地址,这时对文件的读写是能通过操作内存进行的,而不需要使用传统的如fread、fwrite文件操作方式。
MySQL的数据是放在硬盘中的。虽然MySQL也有缓存,但MySQL缓存的是查询的结果,而不是缓存数据。
2.3.2 Redis、MongoDB、MySQL查找数据的区别
Redis的数据是基于“键值对”存储。Redis查找数据,每次都是直奔目标,读写速度当然快。
MongoDB和MySQL中查找数据,有两种模式:知道id或索引,不知道id或索引。前者直奔目标,效率高;后者逐个查找,效率低。
2.3.3 Redis、MongoDB、MySQL适用场景
Redis适用场景:读写频率高的数据、热点数据。
MongoDB适用场景:网站数据(实时的插入、更新与查询),大尺寸、低价值的数据,高伸缩性的场景(数十或者数百台服务器组成的数据库),存储地理坐标的数据;不适合高度事务性的系统、传统的商业智能应用及需要复杂SQL的问题。
MySQL适用场景:事务性的系统(涉及金钱),需要复杂SQL的问题。
2.4 如何选择消息队列软件
2.4.1 为什么使用消息队列
将一些需要花比较多的时间,而且迟点完成不影响整个任务的完成进度的小任务,放到消息队列中,可加快后台请求的响应时间;比如发送邮件、发送短信、推送消息等任务就非常适合放到消息队列中。同时消息队列也能把大量的并发请求变成串行的请求,减轻服务器的负担。
2.4.2 消息队列的工作流程
App后台(队列生产者)把消息推入到消息队列;
守护进程(队列消费者)不断地检测消息队列中有没有新的消息,没有消息就休息一会儿再检测消息队列中有没有新的消息(这样做能避免消息队列占据过多的服务器资源),有消息的话就从消息队列取出消息,用新的线程处理相关的业务,在主线程中继续检测消息队列是否有新消息。
2.4.3 常见的一些消息队列产品
RabbitMQ:重量级的消息队列,适合企业级的开发,其支持大量的协议,比如AMQP、XMPP、SMTP、STOMP;同时RabbitMQ自带了一个Web监控界面,可方便监控队列的情况。
Redis:虽然是一个key-value系统,但其也支持队列这种数据格式,可看作是一个轻量级的消息队列。在App后台架构中Redis被广泛使用,如果把其作为消息队列,能减少项目中的运维成本。
ZeroMQ:号称最快的消息队列,尤其针对大吞吐量的需求场景。
ActiveMQ
2.5 使用分布式服务实现业务的复用
随着业务不断增加,后台系统由一个单一的应用慢慢膨胀为一个巨无霸系统,它聚合了大量的应用和服务,各个模块之间由很多功能重复实现,造成了开发、运维、部署的麻烦。
2.5.1 巨无霸系统的危害
维护上的麻烦
代码管理上的不方便
数据库连接资源的耗尽
ublic boolean offer(E e) {
if (e == null) throw new NullPointerException();
final AtomicInteger count = this.count;
if (count.get() == capacity) return false; // 如果队列已满,直接返回失败
int c = -1;
Node<E> node = new Node<E>(e); // 将数据封装为节点
final ReentrantLock putLock = this.putLock;
putLock.lock();
try {
if (count.get() < capacity) {
enqueue(node); // 入队
c = count.getAndIncrement();
if (c + 1 < capacity) // 如果队列未满,则继续唤醒 putCondition 条件队列
notFull.signal();
}
} finally {
putLock.unlock();
}
if (c == 0) // 如果添加之前的容量为0,说明在出队的时候有竞争,则唤醒 takeCondition
signalNotEmpty(); // 因为是两把锁,所以在唤醒 takeCondition的时候,还需要获取 takeLock
return c >= 0;
}
private void enqueue(Node<E>www.60910.cn node) {
// assert putLock.isHeldByCurrentThread();
// assert last.next == null;
last = last.next = node; // 连接节点,并设置尾节点
}
3. 出队
public E take(www.17093.cn) throws InterruptedException {
E x;
int c = -1;
final AtomicInteger count = this.count;
final ReentrantLock takeLock = this.takeLock;
takeLock.lockInterruptibly(www.078881.cn);
try {
while (count.get(www.18037.cn) == 0) { // 如果队列为空,则加入 takeCondition 条件队列
notEmpty.await();
}
x = dequeue(); // 出队
c = count.getAndDecrement();
if (c > 1)
notEmpty.signal(); // 如果队列还有剩余,则继续唤醒 takeCondition 条件队列
} finally {
takeLock.unlock();
}
if (c == capacity) // 如果取之前队列是满的,说明入队的时候有竞争,则唤醒 putCondition
signalNotFull(); // 同样注意是两把锁
return x;
}
private E dequeue() {
// assert takeLock.isHeldByCurrentThread();
// assert head.item == null;
Node<E> h = head;
Node<E> first = h.next;
h.next = h; // help GC // 将next引用指向自己,则该节点不可达,在下一次GC的时候回收
head = first;
E x = first.item;
first.item = null;
return x;
把重复实现的模块独立部署为远程服务,新增的业务调用远程服务所提供的功能实现相关的业务,不依赖于里面具体的代码实现。当远程服务里面的业务需要发生变化时,只要接口的传入参数和返回值保持不变,就不会影响到调用这些远程服务的业务。
2.5.3 远程服务的实现
REST
REST(Representational State Transfer),即表述性状态传递,它是一组架构约束条件和原则。满足这些约束条件的原则的应用程序或设计就是RESTful。
REST架构的特点:每一个URI代表一种资源;客户端和App后台之间,传递这种资源的某种表述;客户端通过GET、POST、PUT、DELETE等HTTP动词,对App后台资源进行操作,实现“表述性状态传递”。
REST设计原则中最重要的是请求是无状态的。
RPC
RPC(Remote Procedure Call),即远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。
开源的RPC库
阿里巴巴开源Dubbo,其是一个分布式服务框架,致力于提供高性能和透明化的RPC远程调用服务和SOA服务治理方案。
当当网在Dubbo的基础上实现了如下的新功能,并将其命名为Dubbox。
支持REST风格远程调用(HTTP+JSON/XML)。
支持基于Kryo和FST的Java高效序列化实现。
支持基于嵌入式Tomcat的HTTP remoting体系。
将Dubbo中Spring由2.x升级到目前常用的3.x版本。
将Dubbo中的Zookeeper客户端升级到最新的版本,以修正老版本中包含的bug。
2.6 搜索技术入门
常见的开源搜索软件介绍
Lucene
Solr
ElasticSearch
Sphinx
CoreSeek
2.7 定时任务
Linux定时任务Crontab
Java定时任务框架Quartz
从App业务逻辑中提炼API接口的更多相关文章
- SpringBoot自定义异常,优雅解决业务逻辑中的错误
概要 你是不是在为业务逻辑中出现的异常弄的焦头烂额,常常在后台报错,前端却无法提示错误内容,导致用户体验极差?比如下单失败,前端只能提示下单失败,但是却不知道为什么失败,是库存不足,还是余额不足,亦或 ...
- 20.如何从app业务逻辑提炼api接口
在app后端的工作中,设计api是一个很考验设计能力的工作.在项目的初始阶段,只知道具体的业务逻辑,那怎么把业务逻辑抽象和提炼,设计出api呢?通过阅读本文,可解答以上疑惑. 在本文中,是用以前做过的 ...
- 如何调用EcStore中的API接口
EcStore系统已内置了丰富的API接口供外部系统调用(接口列表见文章最下面),外部系统具体如何调用这些API呢? 例如有一个PHP的论坛需要调用ecstore系统内一个商品的详情,则可以使用b2c ...
- PHP性能优化四(业务逻辑中使用场景)
php脚本性能,很多时候依赖于你的php版本.你的web server环境和你的代码的复杂度. Hoare曾经说过“过早优化是一切不幸的根源”.当你想要让你的网站更快运转的时候,你才应该去做优化的事情 ...
- Vue实例中封装api接口的思路 在页面中用async,await调用方法请求
一般我们写小型的项目是用不到封装axios实例 但是当我们写大型项目时 接口有时候多到有上百个接口,那我们在请求一次调用一次接口,接口上好多都是重复的,这个时候我们就可以封装axios实例,既节省了 ...
- 在 Laravel 5 中使用 Repository 模式实现业务逻辑和数据访问的分离
1.概述 首先需要声明的是设计模式和使用的框架以及语言是无关的,关键是要理解设计模式背后的原则,这样才能不管你用的是什么技术,都能够在实践中实现相应的设计模式. 按照最初提出者的介绍,Reposito ...
- coreseek实战(三):全文搜索在php中应用(使用api接口)
coreseek实战(三):全文搜索在php中应用(使用api接口) 这一篇文章开始学习在php页面中通过api接口,使用coreseek全文搜索. 第一步:综合一下前两篇文章,coreseek实战( ...
- iOS开发---业务逻辑
iOS开发---业务逻辑 1. 业务逻辑 iOS的app开发的最终目的是要让用户使用, 用户使用app完成自己的事就是业务逻辑, 业务逻辑的是最显眼开发工作.但是业务逻辑对于开发任务来说, 只是露 ...
- API接口设计
1.场景描述 比如说我们要做一款APP,需要通过api接口给app提供数据.假设我们是做商城,比如我们卖书的.我们可以想象下这个APP大概有哪些内容: 1)首页:banner区域(可以是一些热门书籍的 ...
随机推荐
- Misha, Grisha and Underground CodeForces - 832D (倍增树上求LCA)
Misha and Grisha are funny boys, so they like to use new underground. The underground has n stations ...
- Shell脚本命令图片
查看相关文档:shell脚本1 shell脚本2
- BAT (中国互联网公司三巨头)
BAT,B=百度.A=阿里巴巴.T=腾讯,是中国互联网公司百度公司(Baidu).阿里巴巴集团(Alibaba).腾讯公司(Tencent)三大互联网公司首字母的缩写.百度总部在北京.阿里巴巴总部在浙 ...
- JSP页面导致tomcat内存溢出一例
今天发现一个奇怪的问题,一个tomcat应用,里面只有一个单纯的jsp页面,而且这个jsp页面没有任何java代码——想用这个jsp页面配合tomcat完成一个性能验证.但是用jmeter压测了几分钟 ...
- 通过event记录sql
providers EventServiceProvider.php 添加 protected $listen = [ 'Illuminate\Database\Events\QueryExecute ...
- spring mvc常用注解总结
1.@RequestMapping@RequestMappingRequestMapping是一个用来处理请求地址映射的注解(将请求映射到对应的控制器方法中),可用于类或方法上.用于类上,表示类中的所 ...
- taro 与uni-app对比
https://www.jianshu.com/p/03e08399587e (copy)
- 补充:pyhton 2 和3中的beyts类型
在python2里,bytes == str python2里还有个单独的类型是unicode , 把字符串解码后,就会变成unicode. 既然python2中byets == str,那为什么还要 ...
- 为什么js中要用void 0 代替undefined
这个是Backbone.js中的一句源码 if (callback !== void 0 && 'context' in opts && opts.context == ...
- windows浏览器访问虚拟机开的rabbitmq服务,无法访问
根据这个博主的建议 https://blog.csdn.net/csdnliuxin123524/article/details/78207427 换了一个浏览器上火狐浏览器输入“localhost: ...