单体架构在小微企业比较常见,所有功能集成在一个服务或者一个war包中,一般就是一个应用、一个数据库、一个web容器就可以跑起来。
这样得项目结构功能相对比较少,结构简单,方便维护,扩展性和可靠性比较差,所有功能集成在一个服务中,修改某个功能时,需要所有服务重新打包。后期随着功能的增长,交互的周期会越变越长的,扩展性差。
.png)
服务化架构面向服务的架构,将应用程序根据不同的职责划分为不同的模块,不同的模块直接通过特定的协议和接口进行交互。这样使整个系统切分成很多单个组件服务来完成请求,所有的组件通过交互来满足整体的业务需求。
服务化的优点是可以根据需求通过网络对松散耦合的粗粒度应用组件进行分布式部署、组合和使用。服务层是SOA的基础,可以直接被应用调用,从而有效控制系统中与软件代理交互的人为依赖性。
服务化架构是一套松耦合的架构,服务的拆分原则是服务内部高内聚,服务之间低耦合。
服务化架构的架构图:
.png)
微服务英文名称Microservice,Microservice架构模式就是将整个Web应用组织为一系列小的Web服务。这些小的Web服务可以独立地编译及部署,并通过各自暴露的API接口相互通讯。它们彼此相互协作,作为一个整体为用户提供功能,却可以独立地进行扩。
微服务于服务化架构区别
微服务架构强调业务系统需要彻底的组件化和服务化,一个组件就是一个产品,可以独立对外提供服务
微服务强调每个微服务都有自己独立的运行空间,包括数据库资源。
微服务架构本身来源于互联网的思路,因此组件对外发布的服务强调了采用HTTP Rest API的方式来进行
使用微服务架构能够为我们带来如下好处:
1)服务的独立部署
每个服务都是一个独立的项目,可以独立部署,不依赖于其他服务,耦合性低。
2)服务的快速启动
拆分之后服务启动的速度必然要比拆分之前快很多,因为依赖的库少了,代码量也少了。
3)更加适合敏捷开发
敏捷开发以用户的需求进化为核心,采用迭代、循序渐进的方法进行。服务拆分可以快速发布新版本,修改哪个服务只需要发布对应的服务即可,不用整体重新发布。
4)职责专一,由专门的团队负责专门的服务
业务发展迅速时,研发人员也会越来越多,每个团队可以负责对应的业务线,服务的拆分有利于团队之间的分工。
5)服务可以动态按需扩容
当某个服务的访问量较大时,我们只需要将这个服务扩容即可。
6)代码的复用
每个服务都提供 REST API,所有的基础服务都必须抽出来,很多的底层实现都可以以接口方式提供。
1)分布式部署,调用的复杂性高
2)独立的数据库,分布式事务处理
3)测试的难度提升
4)运维难度的提升
Spring Cloud是一个基于Spring Boot实现的实现微服务云应用开发工具,它为基于JVM的云应用开发中的配置管理、服务发现、断路器、智能路由、微代理、控制总线、全局锁、决策竞选、分布式会话和集群状态管理等操作提供了一种简单的开发方式。
简单说,Spring Cloud 就是用于构建微服务开发和治理的框架集合(并不是具体的一个框架),利用 SpringBoot的开发便利性,巧妙地简化了分布式系统基础设施的开发,基于SpringBoot,会让开发微服务架构非常方便。
Spring Cloud包含了多个子项目(针对分布式系统中涉及的多个不同开源产品),比如:Spring Cloud Config、Spring Cloud Netflix、Spring Cloud CloudFoundry、Spring Cloud AWS、Spring Cloud Security、Spring Cloud Commons、Spring Cloud Zookeeper、Spring Cloud CLI等项目。
.png)
1、请求统一通过API网关(Zuul/Gateway)来访问内部服务.
2、网关接收到请求后,从注册中心(Eureka)获取可用服务
3、由Feign(Ribbon)进行均衡负载后,分发到后端具体实例
4、微服务之间通过Feign进行通信处理业务
5、Hystrix负责处理服务超时熔断并降级
1:约定优于配置
2:开箱即用、快速启动
3:适用于各种环境
4:轻量级的组件
5:组件支持丰富,功能齐全
由于SpringCloud依赖SpringBoot,所以在学习SpringCloud框架之前需要了解下SpringBoot。
1:为所有Spring开发者更快的入门
2:开箱即用,提供各种默认配置来简化项目配置
3:内嵌式容器简化Web项目
4:没有冗余代码生成和XML配置的要求
SpringCould Eureka 是 SpringCould Netflix 微服务套件的一部分,基于 Netflix Eureka 做了二次封装,主要负责实现微服务架构中的服务治理功能。
Spring Cloud Eureka 是一个基于 REST 的服务,并且提供了基于 Java的客户端组件,能够非常方便地将服务注册到 Spring Cloud Eureka 中进行统一管理。
服务治理是微服务架构中必不可少的一部分,服务治理必须要有一个注册中心,除了用 Eureka 作为注册中心外,我们还可以使用 Consul、Etcd、Zookeeper 等来作为服务的注册中心。
SpringBoot各个版本支持得SpringCloud版本号
.png)
推荐使用直接创建springboot项目添加依赖
.png)
子项目中直接引入父项目得依赖关系即可(也可以在每个子服务中单独配置依赖关系)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>cloud221</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-parent</artifactId>
<version>2.0.5.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- Eureka -->
<!-- 服务 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
<version>2.0.3.RELEASE</version>
</dependency>
<!-- 客户端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>2.0.3.RELEASE</version>
</dependency>
</dependencies>
<!--
配置依赖管理
dependencies:添加依赖关系之后就直接引入,子项目继承父项目时,dependencies得依赖关系直接继承
dependencyManagement:
管理依赖关系,不会直接添加依赖关系,
继承父项目时,不会自动继承,需要在dependencies里显示声明依赖并且没有指定version时,会从父项目中继承版本以及依赖关系
-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.SR3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- 仓库:按照顺序依次从仓库中拉去依赖关系 -->
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>repository.springframework.maven.release</id>
<name>Spring Framework Maven Release Repository</name>
<url>http://maven.springframework.org/milestone/</url>
</repository>
<repository>
<id>org.springframework</id>
<url> http://maven.springframework.org/snapshot</url>
</repository>
<repository>
<id>spring-milestone</id>
<name>Spring Maven MILESTONE Repository</name>
<url>http://repo.spring.io/libs-milestone</url>
</repository>
<repository>
<id>spring-release</id>
<name>Spring Maven RELEASE Repository</name>
<url>http://repo.spring.io/libs-release</url>
</repository>
</repositories>
</project> <dependencies>
<!-- Eureka -->
<!-- 服务 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
<version>2.0.3.RELEASE</version>
</dependency>
</dependencies>
<!--
配置依赖管理
dependencies:添加依赖关系之后就直接引入,子项目继承父项目时,dependencies得依赖关系直接继承
dependencyManagement:
管理依赖关系,不会直接添加依赖关系,
继承父项目时,不会自动继承,需要在dependencies里显示声明依赖并且没有指定version时,会从父项目中继承版本以及依赖关系
-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.SR3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement> // 启用Eureka服务:将当前应用程序注册成Eureka注册中心(管理服务)
@EnableEurekaServer
@SpringBootApplication
public class SpringCloudEurekaStart {
public static void main(String[] args) {
SpringApplication.run(SpringCloudEurekaStart.class,args);
}
}eureka:
instance:
# 域名
hostname: localhost
# 客户端
client:
# 禁用注册客户端:Eureka注册中心既可以作为服务端又可以作为客户端,默认会自动注册客户端,不注册客户端,避免自己注册自己
register-with-eureka: false
fetch-registry: false
# 注册中心路径
service-url:
# service-url得取值是Map,没有提示信息得
defalutZone: http://${eureka.instance.hostname}:${server.port}/eureka发现当前没有服务注册
.png)
提供服务
<dependencies>
<!-- Eureka -->
<!-- 服务 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>2.0.3.RELEASE</version>
</dependency>
</dependencies>
<!--
配置依赖管理
dependencies:添加依赖关系之后就直接引入,子项目继承父项目时,dependencies得依赖关系直接继承
dependencyManagement:
管理依赖关系,不会直接添加依赖关系,
继承父项目时,不会自动继承,需要在dependencies里显示声明依赖并且没有指定version时,会从父项目中继承版本以及依赖关系
-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.SR3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>将当前应用程序在注册中心中注册为客户端服务
// 注册成eureka得客户端
// @EnableEurekaClient
// EnableEurekaClient只支持Eureka注册中心,EnableDiscoveryClient支持所有得注册中心
@EnableDiscoveryClient
@SpringBootApplication
public class SpringCloudPorductStart {
public static void main(String[] args) {
SpringApplication.run(SpringCloudPorductStart.class,args);
}
}在注册中心中注册客户端应用程序
server:
port: 8082
spring:
application:
# 应用程序名字
name: springcloud-porduct
eureka:
instance:
hostname: localhost
client:
service-url:
# 注册中心路径:如果服务中心设置了context-path要添加context-path路径
defaultZone: http://localhost:8081/springeureka/eureka.png)
feign:web服务客户端,提供HTTP方式调用接口
openfeign:封装了feign,基于WEB SERVICES得web服务客户端,集成了Spring MVC得注解,可以使用注解得方式完成接口得调用
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>// 将当前应用程序注册为feign得客户端程序
@EnableEurekaClient
@EnableFeignClients
@SpringBootApplication
public class SpringCloudCustomerStart {
public static void main(String[] args) {
SpringApplication.run(SpringCloudCustomerStart.class,args);
}
}server:
port: 8083
spring:
application:
# 应用程序名字
name: springcloud-customer
eureka:
instance:
hostname: localhost
client:
service-url:
# 注册中心路径:如果服务中心设置了context-path要添加context-path路径
defaultZone: http://localhost:8081/springeureka/eureka创建service接口,引入客户端
// 获取SPRINGCLOUD-PORDUCT服务下得
@FeignClient(value = "springcloud-porduct")
public interface PorductUserService {
// 映射生产者对应得方法请求路径
@RequestMapping("/user/getUser")
String getUser();
}@RestController
public class TestController {
@Resource
PorductUserService porductUserService;
@RequestMapping("test")
public String test(){
return porductUserService.getUser();
}
}