Arch. Components 2(三)|学习笔记

简介: 快速学习 Arch. Components 2(三)

开发者学堂课程【高校精品课-上海交通大学-企业级应用体系架构:Arch. Components 2】学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址:https://developer.aliyun.com/learning/course/75/detail/15820


Arch. Components 2(三)

 

内容介绍:

一、有状态、无状态服务

二、scope 的取值


image.png

这时刚才例子的结构,主要代码如下:

UserController.java

@RestController

public class UserController {

@Autowired

private UserService userService;

@GetMapping(value = "/findUser/{id}")

public User findOne(@PathVariable("id") String id) {

System.out.println(userService);

return userService.findUserByld(Integer.valueOf(id));

};

}

UserServicelmpl.java

@Service

public class UserServicelmpl implements UserService {

@Autowired

private UserDao userDao;

@Override

public User findUserByld(Integer id) {

return userDao.findOne(id);

}

}

controler 会发送请求,service 实现类会调用 dao 进行访问。在两个浏览器里面,各自模拟一个客户端发送请求,上述代码没有做 scope 的注解,所以默认是 singleton 的,在下面可以看到,运行 n 多次下来,service instance 只有一个。

image.png

如果将下面的 UserServicelmpl.java 变成 prototype,上面保持 singleton 不变。在两个浏览器运行,会发现在当前配置里,虽然变成 prototype,理论来说,controler 是一个,但是每次访问 UserServicelmpl 时都应该应该创建一个新的对象,但运行后发现仍然只有一个 service instance,为什么呢?

usercontroler 是 singleton 的,因为没有做注解。会靠 spring 注入 userservice,创建 usercontroler 之后,就会创建 UserServicelmpl.java 的对象注入service里,所以每次接收请求的时候,都在调用注入对象的例子,相应方法是finduserbyid。所以尽管是 prototype,只有一个 service instance。这是注入机制导致的。

改变方法,将第一个 controler 也改成 prototype,运行时会发现每次都不一样,也就是每一个会生成一个新的controler 对象,尽管是注入进去的,但 Usercontroler 是多个,所以 UserService 也是多个。

image.png

如果 controler 保持不变,默认 scope 是 singleton。下面是通过 applicationcontext 的方式来获取 service 对象,而不是直接要求注入 userservice。运行结果就是四个对象都不相同。这个方案会更好一些,实际上是在保证controler 只有一个的同时会有四个,而不是像前边,controler 有四个,下面的也有四个。

image.png

把下面换成 session,就会发现2个浏览器里会有2个对象,但在同一个浏览器中发出的请求,会在同一个对象上调用,session 在浏览器里发出多个请求,始终用同一个对象,但是在不同的 session 里,会创建新的对象。

image.png

无法回避有状态的服务,还是会用到 prototype 或 session,不能只用默认的 singleton。在两个浏览器里不能只使用singleton,因为确实有可能需要为不同的用户维护他们各自的状态。一旦用 prototype 或 session,在内存当中,对象不止一个,只要不止一个,对服务器来说都是一种压力,压力随着客户端数量的增大而增多,所以要考虑好系统应该是什么样子的。

在 controler 和 service 两个类里,设有 prototype 和 session,可以看到实例的差异,那到底应该怎么设计呢?

image.png

系统是分层的,有 controler 层,有 DAO 层,DAO 的实现层,实体层,访问实层,service 层等等。在系统里,不能完全回避状态,总是有一些状态是需要维护的。

状态应该集中在某一层,显然,service 层是一个比较好的地方,controler 层是整个应用的入口,大量的请求过来之后,会通过 controler 做分发,会调用 service 进行操作,在入口的地方创建很多对象显然是不合适的,这和 controler层默认是 singleton 是一个道理。

DAO 层是访问下面的数据库,道理来说,不应该和具体的用户相关,多个 DAO 是没有意义的,而且多个 DAO 还会带来问题,在访问底层的数据库时候,多个 DAO 访问就像数据库原理中的事务,多个事务并发执行,是一个难解决的问题,所以 DAO 层不合适。只剩下 service 层是合适的。

所以一个系统在运行的时候,一些是有状态的,一些是无状态的。有状态的应尽量的少,将他放在服务器这层。如果想做得更好,可以把服务层拆得细一些,拆分成两个层,一层无状态服务层,一层有状态服务层。一层的scope是singleton,一层是 prototype 或者 section。在服务层有它的实践逻辑,大多数逻辑中,可能都不需要定义变量,当应用比较复杂之后,把不需要定义自己变量的东西包装在一层,叫做无状态服务层;把需要包装状态的那些服务放在有状态服务层,在无状态服务层之下。

也就是说,上层的无状态层没有任何的属性,只有方法,会调用下面的有状态服务层,有状态服务层包含一些成员方法为不同的用户维护各自的状态。这样才是一种比较理想的方案。可以把有状态的东西限制的尽可能小,整体数量应该进尽可能少。

原因就是有状态的东西会大量消耗内存,如果想节约内存,性能又会大幅下降。原因是在硬盘和内存之间做频繁的换进换出。

本质上就是要节约使用内存,内存的状态和持久化的状态做优化的管理和存储。在这种情况下,把内存使用率提高,尽量让有状态东西少。但有状态的东西是不可能没有的,如果没有就会变成整个服务器端全部是无状态的,可以把状态全部推到客户端处理,但客户端至少要有2个存储用户的会话状态,cookie 和 localstroge 是可以用来存放的。但是把状态存在客户端是需要格外的仔细的。毕竟这两个东西是很容易打开之后篡改的,所以是有隐患的。

好处是服务器端可以不用管状态,服务器端全部都是 singleton对象,状态全部通过 cookie 和 localstroge 写回到客户端。这样需要在 cookie 和 l ocalstroge 的保护上面下功夫。

总的来说,我们要谈的就是用户的会话状态如何保存,有状态、无状态的服务是什么意思,按照给出的例子自己运行可能会有比较深刻的体会。

相关文章
|
存储 运维 安全
阿里认证哪个方向好?考试难不难?
如果想要获得一份好的工作,那么就需要拥有过硬的技能和专业的证书,对于从事信息通讯行业的人来说,拥有一份阿里云证书,对于提升自己的职业竞争力是有很大的帮助的。
|
网络架构
静态路由(详细理解+实例精讲)
本文详细的介绍静态路由,内含详细的实例解析,该文你值得拥有。
|
存储 人工智能 算法
《探秘AI绿色计算:降低人工智能硬件能耗的热点技术》
在人工智能快速发展的背景下,硬件能耗问题日益突出。为实现绿色计算,降低能耗成为关键课题。新型硬件架构如CRAM、自旋电子器件和量子计算硬件,以及优化的低功耗芯片设计、3D集成技术和液冷散热技术等,正崭露头角。同时,硬件与软件协同优化,通过模型压缩、算法适配等手段,进一步提升能效。这些技术将推动AI向更绿色、高效的方向发展,助力应对全球气候变化。
660 19
|
编解码 人工智能 自然语言处理
让大模型理解手机屏幕,苹果多模态Ferret-UI用自然语言操控手机
【5月更文挑战第29天】苹果推出Ferret-UI,一个结合图像识别和自然语言处理的多模态大语言模型,允许用户通过自然语言指令操控手机。该系统能适应不同屏幕布局,识别UI元素并执行相应操作,有望变革手机交互方式,提升无障碍体验,并在测试和开发中发挥作用。但需面对屏幕多样性及准确性挑战。[论文链接](https://arxiv.org/pdf/2404.05719.pdf)
638 3
波士顿房价数据集 Boston house prices dataset
波士顿房价数据集 Boston house prices dataset
430 2
|
自然语言处理
论文推荐:用多词元预测法提高模型效率与速度
《Better & Faster Large Language Models via Multi-token Prediction》论文提出了一种多词元预测框架,改善了大型语言模型(LLMs)的样本效率和推理速度。该方法通过一次预测多个词元,而非单个词元,提高了模型在编程和自然语言任务中的性能。实验显示,多词元预测在HumanEval和MBPP任务上性能提升,推理速度最高可提升3倍。此外,自我推测解码技术进一步优化了解码效率。尽管在小模型中效果不明显,但该方法为大模型训练和未来研究开辟了新途径。
651 0
|
图形学
【制作100个unity游戏之26】unity2d横版卷轴动作类游戏1(附带项目源码)
【制作100个unity游戏之26】unity2d横版卷轴动作类游戏1(附带项目源码)
427 0
|
存储 安全 测试技术
数据库怎么评测
数据库怎么评测
446 8
|
JavaScript 前端开发 Java
淘宝/天猫获取sku详细信息 API接口(如何抓取别人的sku图淘宝)
淘宝/天猫平台提供了获取商品SKU(Stock Keeping Unit,库存量单位)详细信息的API接口。SKU通常代表一种具有独特属性的商品变体,如颜色、尺寸等。为了获取淘宝/天猫商品的SKU详细信息,您可以遵循以下步骤:
|
安全 Python
使用eval函数需要注意哪些方面
使用eval函数需要注意哪些方面
504 0