Spring Cloud 是一套完整的微服务解决方案,基于 Spring Boot 框架,准确的说,它不是一个框架,
而是一个大的容器,它将市面上较好的微服务框架集成进来,从而简化了开发者的代码量。
Spring Cloud 是什么?
Spring Cloud 是一系列框架的有序集合,它利用 Spring Boot 的开发便利性简化了分布式系统的开发,
比如服务发现、服务网关、服务路由、链路追踪等。Spring Cloud 并不重复造轮子,而是将市面上开发得
比较好的模块集成进去,进行封装,从而减少了各模块的开发成本。换句话说:Spring Cloud 提供了
构建分布式系统所需的“全家桶”。
Spring Cloud 现状
目前,国内使用 Spring Cloud 技术的公司并不多见,不是因为 Spring Cloud 不好,主要原因有以下几点:
1.Spring Cloud 中文文档较少,出现问题网上没有太多的解决方案。
2.国内创业型公司技术老大大多是阿里系员工,而阿里系多采用 Dubbo 来构建微服务架构。
3.大型公司基本都有自己的分布式解决方案,而中小型公司的架构很多用不上微服务,
所以没有采用 Spring Cloud 的必要性。
但是,微服务架构是一个趋势,而 Spring Cloud 是微服务解决方案的佼佼者
Spring Cloud 优缺点
其主要优点有:
1.集大成者,Spring Cloud 包含了微服务架构的方方面面。
2.约定优于配置,基于注解,没有配置文件。
3.轻量级组件,Spring Cloud 整合的组件大多比较轻量级,且都是各自领域的佼佼者。
4.开发简便,Spring Cloud 对各个组件进行了大量的封装,从而简化了开发。
5.开发灵活,Spring Cloud 的组件都是解耦的,开发人员可以灵活按需选择组件。
Spring Cloud 和 Dubbo 对比
Dubbo 只是实现了服务治理,而 Spring Cloud 实现了微服务架构的方方面面,服务治理只是其中的一个方面。
Spring Cloud 比较全面,而 Dubbo 由于只实现了服务治理,需要集成其他模块,需要单独引入,
增加了学习成本和集成成本。
什么是 Spring Boot
Spring Boot 是由 Pivotal 团队提供的基于 Spring 的全新框架,其设计目的是为了简化
Spring 应用的搭建和开发过程。该框架遵循“约定大于配置”原则,采用特定的方式进行配置,
从而使开发者无需定义大量的 XML 配置。通过这种方式,Spring Boot 致力于在蓬勃发展的快速应用
开发领域成为领导者。
Spring Boot 并不重复造轮子,而且在原有 Spring 的框架基础上封装了一层,并且它集成了一些类库,
用于简化开发。换句话说,Spring Boot 就是一个大容器。
Spring Boot 官方推荐使用 Maven 或 Gradle 来构建项目,本教程采用 Maven。
properties 和 yaml
Spring Boot 整个应用程序只有一个配置文件,那就是 .properties 或 .yml 文件。
Spring Boot 对每个配置项都有默认值。
我们也可以添加配置文件,用以覆盖其默认值,这里以 .properties 文件为例,
首先在 resources 下新建一个名为 application.properties
(注意:文件名必须是 application)的文件,键入内容为:
server.port=8081
server.servlet.context-path=/api
并且启动 main 方法,这时程序请求地址则变成了:http://localhost:8081/api/hello。
Spring Boot 支持 properties 和 yaml 两种格式的文件,文件名分别对应 application.properties
和 application.yml
可以看出 properties 是以逗号隔开,而 yaml 则换行+ tab 隔开,这里需要注意的是冒号后面必须空格,
否则会报错。yaml 文件格式更清晰,更易读,这里作者建议大家都采用 yaml 文件来配置。
打包、运行
Spring Boot 打包分为 war 和 jar两个格式,下面将分别演示如何构建这两种格式的启动包。
在 pom.xml 加入如下配置:
这个时候运行 mvn package 就会生成 war 包,然后放到 Tomcat 当中就能启动,但是我们单纯这样配置
在 Tomcat 是不能成功运行的,会报错,需要通过编码指定 Tomcat 容器启动,修改 HelloController 类:
其中,Application.java 是程序的启动类,Startup.java 是程序启动完成前执行的类,
WebConfig.java 是配置类,所有 bean 注入、配置、拦截器注入等都放在这个类里面。
Spring Boot 进阶
Spring Boot 和传统的 SpringMVC 架构的对比,我们清晰地发现 Spring Boot 的好处,
它使我们的代码更加简单,结构更加清晰。
Spring Boot 是一个大容器,它将很多第三方框架都进行了集成,我们在实际项目中用到哪个模块,
再引入哪个模块。比如我们项目中的持久化框架用 MyBatis,则在 pom.xml 添加如下依赖:
yaml/properties 文件
我们知道整个 Spring Boot 项目只有一个配置文件,那就是 application.yml,Spring Boot 在启动时,
就会从 application.yml 中读取配置信息,并加载到内存中。上一篇我们只是粗略的列举了几个配置项,
其实 Spring Boot 的配置项是很多的,本文我们将学习在实际项目中常用的配置项
(注:为了方便说明,配置项均以 properties 文件的格式写出,后续的实际配置都会写成 yaml 格式)。
多环境配置
在一个企业级系统中,我们可能会遇到这样一个问题:开发时使用开发环境,测试时使用测试环境,
上线时使用生产环境。每个环境的配置都可能不一样,比如开发环境的数据库是本地地址,
而测试环境的数据库是测试地址。那我们在打包的时候如何生成不同环境的包呢?
这里的解决方案有很多:
1.每次编译之前手动把所有配置信息修改成当前运行的环境信息。这种方式导致每次都需要修改,相当麻烦,
也容易出错。
2.利用 Maven,在 pom.xml 里配置多个环境,每次编译之前将 settings.xml
里面修改成当前要编译的环境ID。这种方式会事先设置好所有环境,缺点就是每次也需要手动指定环境,
如果环境指定错误,发布时是不知道的。
3.创建 application.yml 文件,在里面添加如下内容:
spring: profiles: active: dev
含义是指定当前项目的默认环境为 dev,即项目启动时如果不指定任何环境,Spring Boot 会自动从
dev环境文件中读取配置信息。我们可以将不同环境都共同的配置信息写到这个文件中。
然后创建多环境配置文件,文件名的格式为:application-{profile}.yml,其中,{profile}
替换为环境名字,如 application-dev.yml,我们可以在其中添加当前环境的配置信息,如添加数据源:
这样,我们就实现了多环境的配置,每次编译打包我们无需修改任何东西,编译为 jar 文件后,运行命令:
java -jar api.jar --spring.profiles.active=dev
其中 --spring.profiles.active 就是我们要指定的环境。
常用注解
@SpringBootApplication
我们可以注意到 Spring Boot 支持 main 方法启动,在我们需要启动的主类中加入此注解,
告诉 Spring Boot,这个类是程序的入口。
SpringBootConfiguration 表示 Spring Boot 的配置注解,EnableAutoConfiguration 表示自动配置,
ComponentScan 表示 Spring Boot 扫描 Bean 的规则,比如扫描哪些包。
@Bean
这个注解是方法级别上的注解,主要添加在 @Configuration 或 @SpringBootConfiguration 注解的类,
有时也可以添加在 @Component 注解的类。它的作用是定义一个Bean。
@Value
通常情况下,我们需要定义一些全局变量,都会想到的方法是定义一个 public static 变量,在需要时调用,
是否有其他更好的方案呢?答案是肯定的。下面请看代码:
@Value("${server.port}")
String port;
@RequestMapping("/hello")
public String home(String name) {
return "hi "+name+",i am from port:" +port;
}
其中,server.port 就是我们在 application.yml 里面定义的属性,我们可以自定义任意属性名,通过 @Value 注解就可以将其取出来。
它的好处不言而喻:
1.定义在配置文件里,变量发生变化,无需修改代码。
2.变量交给Spring来管理,性能更好。
注:Spring Boot 本身基于 Spring 开发的,因此,本文不再讲解其他 Spring 的注解。
自定义 JSON 解析
Spring Boot 中 RestController 返回的字符串默认使用 Jackson 引擎,它也提供了工厂类,
我们可以自定义 JSON 引擎,本节实例我们将 JSON 引擎替换为 fastJSON,首先需要引入 fastJSON:
模板引擎
在传统的 SpringMVC 架构中,我们一般将 JSP、HTML 页面放到 webapps 目录下面,
但是 Spring Boot 没有 webapps,更没有 web.xml,如果我们要写界面的话,该如何做呢?
Spring Boot 官方提供了几种模板引擎:FreeMarker、Velocity、Thymeleaf、Groovy、mustache、JSP。
这里以 FreeMarker 为例讲解 Spring Boot 的使用。
首先引入 FreeMarker 依赖:
其中 static 目录用于存放静态资源,譬如:CSS、JS、HTML 等,templates 目录存放模板引擎文件,
我们可以在 templates 下面创建一个文件:index.ftl(freemarker 默认后缀为 .ftl),并添加内容:
=========================================================================================
什么是Spring Cloud
Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统
基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,
都可以用Spring Boot的开发风格做到一键启动和部署。
Spring并没有重复制造轮子,它只是将目前各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,
通过Spring Boot风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、
易部署和易维护的分布式系统开发工具包。
微服务是可以独立部署、水平扩展、独立访问(或者有独立的数据库)的服务单元,
Spring Cloud就是这些微服务的大管家,采用了微服务这种架构之后,项目的数量会非常多,
Spring Cloud做为大管家就需要提供各种方案来维护整个生态。
Spring Boot和Spring Cloud的关系
Spring Boot 是 Spring 的一套快速配置脚手架,可以基于Spring Boot 快速开发单个微服务,
Spring Boot专注于快速、方便集成的单个微服务个体,Spring Cloud关注全局的服务治理框架;
Spring Boot使用了默认大于配置的理念,很多集成方案已经帮你选择好了,能不配置就不配置,
Spring Cloud很大的一部分是基于Spring Boot来实现,可以不基于Spring Boot吗?不可以。
Spring Boot可以离开Spring Cloud独立使用开发项目,但是Spring Cloud离不开Spring Boot,
属于依赖的关系。
Spring -> Spring Boot > Spring Cloud 这样的关系。
1.Spring Cloud并不是一套高深的技术,普通的Java程序员经过一到俩个月完全就可以上手,
但前期需要一个比较精通人的来带队。
2.现在Spring Cloud越来越火的情况下,各种资源也越来越丰富,查看官方文档和示例,
现在很多优秀的博客在写spirng cloud的相关教程,我这里收集了一些Spring Boot和Spring Cloud的
相关资源可以参考,找到博客也就找到人和组织了。
3.Spring Cloud只是后端服务治理的一套框架,唯一和前端有关系的是thymeleaf,
Spring推荐使用它做模板引擎。一般情况下,前端app或者网页通过zuul来调用后端的服务,
如果包含静态资源也可以使用nginx做一下代理转发。
4.session共享有很多种方式,比如使用tomcat sesion共享机制,
但我比较推荐使用redis缓存来做session共享。完全可以分批引入,我在上一家公司就是分批过渡上线,
新旧项目通过zuul进行交互,分批引入的时候,最好是新业务线先使用Spring Cloud,老业务做过渡,
当完全掌握之后在全部替换。如果只是请求转发,zuul的性能不一定比nginx低,
但是如果涉及到静态资源,还是建议在前端使用nginx做一下代理。另外Spring Cloud有配置中心,
可以非常灵活的做所有配置的事情。
5.多环境不同配置,Spring Boot最擅长做这个事情了,使用不同的配置文件来配置不同环境的参数,
在服务启动的时候指明某个配置文件即可,例如:java -jar app.jar --spring.profiles.active=dev
就是启动测试环境的配置文件;Spring Cloud 没有提供发布平台,
因为jenkins已经足够完善了,推荐使用jenkins来部署Spring Boot项目,会省非常多的事情;
6.Spring Cloud只做服务治理,其它具体的功能都是集成了各种框架来解决而已;
还是强调Spring Cloud只是服务治理。
目前Spring Cloud是所有微服务治理中最优秀的方案,也是一个趋势,
未来一两年可能就会像Spring一样流行,早接触早学习岂不更好。
Spring Boot学习资料汇总:
Spring Cloud学习资料汇总 :
=============================================================================================
SpringCloud架构设计
1.是web服务器的选型,选择的是nginx+keepalived,减少了三次握手的次数,提高了连接效率。
keepalived做nginx的负载,虚拟一个vip对外,两个nginx做高可用,nginx本身反向代理zuul集群。
2.api gateway,这里的zuul很多人诟病,说是速度慢推荐直接用nginx,这里我还是推荐使用zuul的,毕竟zuul含有拦截器和反向代理,在权限管理、单点登录、用户认证时候还是很有用的,而且zuul自带ribbon负载均衡,如果你直接用nginx,还需要单独做一个feign或者ribbon层,用来做业务集群的负载层,毕竟直接把接口暴露给web服务器太危险了。
3.redis缓存池,这个用来做session共享,分布式系统session共享是一个大问题。同时呢,
redis做二级缓存对降低整个服务的响应时间,并且减少数据库的访问次数是很有帮助的。
4.eurake注册中心这个高可用集群,这里有很多细节,比如多久刷新列表一次,
多久监测心跳什么的,都很重要。
5.消息队列,这个必须的,分布式系统不可能所有场景都满足强一致性,这里只能由消息队列来作为缓冲,
这里我用的是Kafka。分布式事物,我认为这是分布式最困难的,因为不同的业务集群都对应自己的数据库,
互相数据库不是互通的,互相服务调用只能是相互接口,有些甚至是异地的,
这样造成的结果就是网络延迟造成的请求等待,网络抖动造成的数据丢失,这些都是很可怕的问题,
所以必须要处理分布式事物。我推荐的是利用消息队列,采取二阶段提交协议配合事物补偿机制,
具体的实现需要结合业务,这里篇幅有限就不展开说了。