SOA和微服务两者的区别:

SOA关注的是服务的重用性及解决信息孤岛问题

微服务关注的是解耦,虽然解耦和可重用性从特定发角度来看是一样,但是本质上是有区别的,解耦是降低业务之间的耦合度,而重用性关注的是服务的重用。

微服务会更多发关注在DevOps的持续交付上,因为服务粒度细化之后使得开发运维变得更加重要,因此微服务与容器化的技术的结合更加紧密。

微服务架构的优点:

复杂度可控:通过对共享业务更细粒度发拆分,一个服务只需要关注一个特定的业务领域。并通过定义良好的接口清晰表示服务边界。由于体积小、复杂度低,开发、维护会更加简单。

技术选型更灵活:每个微服务都由不同的团队维护,所以可以结合业务特性自由选择技术栈。

可扩展性更强:可以根据每个微服务的性能要求和业务特点来对服务灵活扩展,比如通过增加单个服务的集群规模,提升部署了该服务的节点的硬件配置

独立部署:由于每个微服务都是一个独立运行的进程,所以可以实现独立部署。当某个微服务发生变更时不需要重新编译部署整个应用,并且单个微服务的代码量比较小,是的发布更加高效。

容错性:在微服务架构中,如果某一服务发生故障,我们可以是故障隔离在单个服务中,其他服务可以通过重试、降级等机制来实现应用层面的容错。

微服务面临的挑战:

故障排查:一次请求可能会经历多个不同的微服务的多次交互,交互的链路可能会比较长,每个微服务会产生自己的日志,在这种情况下如果出现一个故障,开发人员定位问题的根源会比较难,服务之间也不能用debug

服务监控:在微服务架构中,服务监控的开销会非常大,不仅要对整个链路进行监控,还需要对每一个微服务都是先一套类似单体架构的监控。

分布式架构的复杂性:微服务本身构建的是一个分布式系统,分布式系统设计服务之间的远程通信,而网络通信中网络的延迟和网络故障是无法避免的,从而增加了应用程序的复制度

服务依赖:微服务的数量增加之后,各个服务之间会存在更多的依赖关系,使得系统整体更加复制,修改时可能涉及多个服务的修改

运维成本:在微服务中,需要保证几百个微服务的正常运行,对于运维的挑战是巨大的,比如单个服务流量激增时如何扩容等

微服务解决方案之Spring Cloud

什么是Spring Cloud?

Spring Cloud提供了一些可以让开发者快速构建微服务应用的工具,比如配置管理、服务发现、熔断、智能路由等,这些服务可以在任何分布式环境下更好地工作。Spring Cloud主要致力于解决如下问题:

分布式版本化控制

服务注册与发现

服务路由

服务调用

负载均衡

断路器

全局锁

选举及群体状态

分布式消息

Spring Cloud是一套规范,而Spring Cloud Netflix,Spring Cloud Consul,Speing Cloud Alibaba才是Spring Cloud 规范的实现。

Spring Cloud Netflix

Spring Cloud Netflix 主要为微服务架构下的服务治理提供解决方案,包括一下组件:

Eureka , 服务注册与发现

Zuul,服务网关

Ribbon,负载均衡

Feign,远程服务的客户端代理

Hystrix,断路器,提供服务熔断和限流功能

Hystrix Dashboard,监控面板

Turbine,将各个服务实例上的Hystrix监控信息进行统一聚合

Spring Cloud Alibaba

Spring Cloud Alibaba 生态下的主要功能组件,这些组件包括开源组件和阿里云产品组件,云产品是需要付费的

Sentinel,流量控制和服务降级

Nacos,服务注册与发现

Nacos,分布式配置中心

RocketMQ,消息驱动

Seate,分布式事务

Dubbo,RPC通信

OSS,阿里云对象存储

相较于Spring Cloud Netflix来说,Spring Cloud Alibaba 的优势如下:

  1. Alibaba的开源组件在没有织入Spring Cloud生态之前,已经在各大公司广泛应用,所以集成到Spring Cloud生态使得开发者能够很轻松地实现技术整合及转移
  2. Alibaba的开源组件在服务治理上和处理高并发能力上有天然的优势,所以相比Spring Cloud Netflix,Spring Cloud Alibaba在服务治理这一块更适合国内的技术场景,同时Spring Cloud Alibaba在功能上不仅完全覆盖Spring Cloud Netflix原生特性,而且还提供了更加稳定和成熟的实现

Spring IoC/DI

IoC和DI的全程分别是控制反转和依赖注入。

IoC实际上就是把对象的生命周期托管到Spring容器中,而反转是指对象的获取方式被反转了。

传统意义上对象的创建方式,客户端类如果需要获得User及UserDetail,需要通过new 来创建,这种方式会使代码之间的耦合度非常高

增加了IoC之后,客户端类获得User及UserDdtail对象实例时,不再通过new来构建,而是直接从IoC容器中获得。那么Spring IoC容器中的对象是什么时候构建的呢?在早期的Spring中,主要通过XML的方式来定义Bean,Spring会解析XML文件,把定义的Bean装载到IoC容器中。

DI也就是依赖注入,简单理解就是IoC容器运行期间,动态地把某种依赖关系注入组件中。

其实很简单,我们只需要在Spring的配置文件中描述Bean之间的依赖关系,IoC容器在解析该配置文件的时候,会根据Bean的依赖关系进行注入,这个过程就是依赖注入

<Bean id="user" class="User">
<property name="userDetail" ref="userDetail"/>
</bean>
<bean id="userDetail" class="UserDetail"/>

实现依赖注入的方法有三种,分别是接口注入、构方法注入和setter方式注入。不过现在基本上都基于注入的方式来描述Bean之间的依赖关系,比如@Autowired、@Inject和@Resource

Bean装配方式的升级

XML配置形式的变化:

在早期的Spring中,我们会基于XML配置文件来描述Bean及Bean的依赖关系,使用JavaConfig形式之后,只需要使用@Configuration注解即可,它等同于XML的配置形式

@Configuration
public class SpringConfigClass{
//Bean描述
}

Bean装载方式的变化

基于XML形式的装载方式

<bean id="beanDefine" class="com.gupaoedu.spring.BeanDefine" />

基于JavaConfig的配置形式,可以通过@Bean注解将一个对象注入IoC容器中,默认情况下采用方法名称作为该Bean的id

@Configuration
public class SpringConfigClass{
@Bean
public BeanDefine beanDefine(){
return new BeanDefine();
}
}

依赖注入的变化

在XML形式中,可以通过三种方式来完成依赖注入,比如setter方式注入:

<bean id="beanDefine" class="com.gupaoedu.spring.BeanDefine">
<property name="depenencyBean" ref="de[pencyBean"/>
</bean>
<bean id="depencyBean" class="……"/>

在JavaConfig中,可以这样来表述:

@Configuration
public class SpringConfigClass{
@Bean
public BeanDefine beanDefine(){
BeanDefine beanDefine=new BeanDefine();
beanDefine.setDependencyBean(dependencyBean())
return beanDefine;
}
@Bean
public DependencyBean dependencyBean(){
return new DependencyBean();
}
}

其他配置的变化

除了前面说的几种配置,还有其他常见的配置,比如:

@ComponentScan对应XML形式的<context:component-scan base-package=""/>,它会扫描指定包路径下带有@Service、@Repository、@Controller、@Compent等注解类,将这些类装载到IoC容器。

@Import对应XML形式的<import resource=""/>,导入其他配置文件

虽然通过注解的方式来配置Bean,可以在一定程度上减少XML配置带来的问题,但是从某一方面来说它只是换汤不换药,本质问题仍然没有解决,比如

依赖过多。Spring可以整合几乎所有常用的技术框架,比如JSON、MyBatis、Redis、Log等,不同依赖包的版本很容易导致版本的兼容问题

配置太多。以Spring使用JavaConfig方式整合MyBatis为例,需要配置注解驱动、配置数据源、配置MyBatis、配置事务管理器等,这些只是集中一个技术组件需要的基础配置,在一个项目中这类配置很多,开发者需要做很多类似的重复工作。

运行和部署很繁琐。需要先把项目打包,再部署到容器上。

Spring Boot的价值

如何理解约定优于配置

约定优于配置是一种软件设计模式,目的在于减少配置的数量或者降低理解难度,从而提升开发效率。

在Spring Boot中,约定优于配置的思想主要体现在以下方面(包括但不限于):

  1. Maven项目结构的约定
  2. Spring Boot中默认的配置文件及配置文件中配置属性的约定
  3. 对于Spring MVC的依赖,自动依赖内置的Tomcat容器
  4. 对于Starter组件自动完成配置

Spring Boot的核心

  1. Spring Boot是基于Spring Framework体系来构建的,它的核心:
  2. Starter 组件,提供开箱即用的组件
  3. 自动装配,自动根据上下文完成Bean的装配
  4. Actuator,Spring Boot应用的监控。
  5. Spring Boot CLI,给予命令行工具快速构建Spring Boot应用

其中最核心的部分应该是自动装配,Sarter组件的核心部分也是基于自动装配来实现的。