微服务是一种开发软件的架构和组织方法,其中软件由通过明确定义的 API 进行通信的小型独立服务组成。这些服务由各个小型独立团队负责。
微服务架构使应用程序更易于扩展和更快地开发,从而加速创新并缩短新功能的上市时间。
可以对微服务架构中的每个组件服务进行开发、部署、运营和扩展,而不影响其他服务的功能。这些服务不需要与其他服务共享任何代码或实施。各个组件之间的任何通信都是通过明确定义的 API 进行的。
每项服务都是针对一组功能而设计的,并专注于解决特定的问题。如果开发人员逐渐将更多代码增加到一项服务中并且这项服务变得复杂,那么可以将其拆分成多项更小的服务。
微服务促进若干小型独立团队形成一个组织,这些团队负责自己的服务。各团队在小型且易于理解的环境中行事,并且可以更独立、更快速地工作。这缩短了开发周期时间。您可以从组织的总吞吐量中显著获益。
通过微服务,您可以独立扩展各项服务以满足其支持的应用程序功能的需求。这使团队能够适当调整基础设施需求,准确衡量功能成本,并在服务需求激增时保持可用性。
微服务支持持续集成和持续交付,可以轻松尝试新想法,并可以在无法正常运行时回滚。由于故障成本较低,因此可以大胆试验,更轻松地更新代码,并缩短新功能的上市时间。
微服务架构不遵循“一刀切”的方法。团队可以自由选择最佳工具来解决他们的具体问题。因此,构建微服务的团队可以为每项作业选择最佳工具。
将软件划分为小型且明确定义的模块,让团队可以将功能用于多种目的。专为某项功能编写的服务可以用作另一项功能的构建块。这样应用程序就可以自行引导,因为开发人员可以创建新功能,而无需从头开始编写代码。
服务独立性增加了应用程序应对故障的弹性。在整体式架构中,如果一个组件出现故障,可能导致整个应用程序无法运行。通过微服务,应用程序可以通过降低功能而不导致整个应用程序崩溃来处理总体服务故障。
单体架构:将业务的所有功能集中在一个项目中开发,打成一个包部署。
优点:
缺点:
分布式架构:根据业务功能对系统进行拆分,每个业务模块作为独立项目开发,称为一个服务。
优点:
分布式架构的要考虑的问题
微服务是一种经过良好架构设计的分布式架构方案,微服务架构特征:
微服务结构这种方案需要技术框架来落地,全球的互联网公司都在积极尝试自己的微服务落地技术。在国内最知名的就是SpringCloud 和 阿里巴巴的Dubbo。
微服务拆分绝非是一个大跃进的过程,拆分时机不对,很容易把一个应用拆分的七零八落,最终大大增加运维成本,却不会带来明显收益。
微服务拆分的过程,是基于某个痛点出发,是业务真正遇到快速迭代和高并发等问题,如果不拆分,将对于业务的发展带来影响,只有这个时候,微服务的拆分才是有确定收益的,增加的运维成本才是值得的。
互联网时代,业务快速变化,应用的交付需要快速响应式交付。通过微服务架构,采用快速迭代的方式进行架构演进,将系统拆分成多个独立的微服务,微服务之间彼此独立,通过服务接口交互。当某个微服务遇到问题时发版修复,不会导致整个系统不可用,从而支撑业务的快速试错。
单体应用开发通常是几十人开发一个系统,代码管理时经常会遇到代码提交冲突。微服务架构通过快速迭代可实现开发独立,将系统拆分成不同的微服务,每个微服务对外提供接口,其他依赖服务不用关注具体的实现细节,只需保证接口正确即可。每几个人维护一个服务模块,降低代码冲突的概率,出现冲突时也可快速解决。
传统模式单次上线的需求通常较多、风险较大,小功能的错误可能会导致大功能无法上线。因此每次上线都会带来较大的工作量。
微服务架构对于快速迭代可带来独立上线的效果。微服务拆分后,在服务接口稳定的情况下,不同的微服务可独立上线。上线的次数增多,单次上线的需求量变小,可随时回滚,风险变小,时间变短,影响面小,从而加快迭代速度。
互联网时代,业务应用的高并发要求越来越高,单体应用虽然可以通过部署多份承载一定的并发量,但是会造成资源非常浪费。有的业务需要扩容,例如下单和支付,有的业务不需要扩容,例如注册。如果一起扩容,消耗的资源可能是拆分后的几倍。因此,对于并发量大的系统,选择微服务拆分是很有必要的。
单一职责原则:每个微服务只需关心自己的业务规则,确保职责单一,避免职责交叉,耦合度过高将会造成代码修改重合,不利于后期维护。
服务自治原则:每个微服务的开发,必须拥有开发、测试、运维、部署等整个过程,并且拥有自己独立的数据库等,可以完全把其当作一个单独的项目来做,而不牵扯到其他无关业务。
轻量级通信原则:微服务间需通过轻量级通信机制进行交互。首先是体量较轻,其次是需要支持跨平台、跨语言的通信协议,再次是需要具备操作性强、易于测试等能力,如:REST通信协议。
接口明确原则:明确接口要实现的内容,避免接口依赖,如A接口的改动会导致B接口的改动。
持续演进原则:单体架构向微服务架构拆分过程中,无法做到一蹴而就,刚开始不建议拆分太小,过度拆分将会带来架构复杂度的急剧升高,开发、测试、运维等环节很难快速适应,将会导致故障率大幅增加,可用性降低,非必要情况,应逐步拆分细化,持续演进,避免微服务数量的瞬间爆炸性增长。
微服务的拆分应遵循上述拆分时机、拆分原则,并选择合适的拆分方法,逐步拆分。在实际拆分过程中,除了要遵循拆分原则,还要从实际业务领域出发,并结合考虑非业务的因素,比如需求变更的频率、高性能、安全性、团队规模以及技术异构等因素。这些非业务因素对于最终落地也会起到决定性的作用,因此在微服务拆分时需要重点关注。
基于领域模型,围绕业务界限上下文边界,将同类业务划归为一个微服务,按单一职责原则、功能完整性进行微服务的拆分。
需要识别业务需求的变动频率,考虑业务变化频率与相关度,将业务需求变动较高和功能相对稳定的业务进一步分离拆分。
因为需求的经常性变动必然会导致代码的频繁修改和版本发布,这种拆分可以有效降低频繁发布版本的业务对不需要经常发布版本的业务的影响。
需要识别性能压力较大的业务。因为对性能指标要求高的业务在资源需求上会比其他业务的高,这样可能会拖累其他业务,也会造成资源无谓的浪费。为了降低对系统整体性能和资源要求的影响,我们将对性能方面有较高要求的业务与对性能要求不高的业务进一步拆分。
除非有意识地优化组织架构,否则微服务的拆分应尽量避免对组织架构和团队的调整,避免由于功能的重新划分,而增加大量且不必要的团队之间的沟通成本。
在进行微服务拆分和组建项目团队时,应尽量将沟通边界控制在团队内。
对于有特殊安全要求的业务,应独立出来,避免因不同的安全要求,而带来不必要的成本,或带来泄密的风险。
虽然都是在同一个业务领域内,但由于各种条件的限制,在技术实现时可能会存在较大的差异(存在技术异构的问题)。
大部分都是采用Java语言实现,但由于业务场景或者技术条件的限制,有的可能需要采用Go语言实现,甚至有的采用大数据技术架构。
1、RestTemplate类可用于在应用中调用rest服务:
2、在Spring应用程序中访问第三方REST服务与使用Spring RestTemplate类有关。RestTemplate类的设计原则与许多其他Spring *模板类(例如JdbcTemplate、JmsTemplate)相同,为执行复杂任务提供了一种具有默认行为的简化方法。
3、RestTemplate默认依赖JDK提供http连接的能力(HttpURLConnection),如果有需要的话也可以通过setRequestFactory方法替换为例如 Apache HttpComponents、Netty或OkHttp等其它HTTP library。
4、考虑到RestTemplate类是为调用REST服务而设计的,因此它的主要方法与REST的基础紧密相连就不足为奇了,后者是HTTP协议的方法:HEAD、GET、POST、PUT、DELETE和OPTIONS。
例如,RestTemplate类具有headForHeaders()、getForObject()、postForObject()、put()和delete()等方法。
package com.cloud.order;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@MapperScan("com.cloud.order.mapper")
@SpringBootApplication
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
package com.cloud.order.service;
import com.cloud.order.mapper.OrderMapper;
import com.cloud.order.pojo.Order;
import com.cloud.order.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
@Service
public class OrderService {
@Autowired
private OrderMapper orderMapper;
@Autowired
private RestTemplate restTemplate ;
public Order queryOrderById(Long orderId) {
// 1.查询订单
Order order = orderMapper.findById(orderId);
//2.利用restTemplate 发起http请求,查询用户
String url = "localhost:8880/user/"+order.getId();
User user = restTemplate.getForObject(url,User.class);
//设置用户信息
order.setUser(user);
// 4.返回
return order;
}
}
参考文章:https://blog.csdn.net/a6470831/ article/details/124215984 https://blog.csdn.net /a6470831/article/details/124235654