1.为什么用微服务
首先单个系统虽然在初期可以很方面快捷的进行开发、使用,但是随着系统越来越庞大,开发维护的人员交换,开发与维护的成本越来越大,且难以控制,在这种情况下微服务诞生了,他们将系统中不同模块拆分成多个不同的服务,这些服务都是能够独立部署、扩展和开发的,不同的服务运行不会影响到其他服务,节约成本的同时提高了系统的瓶顶。
2.微服务九大特征
服务组件化、按业务组织团队、做“产品”的态度、智能端点与哑管道、去中心化治理、去中心化管理数据、基础设施自动化、容错设计、
3.为什么选择SpringCloud
国内目前已经有很多微服务架构了,如:阿里的Dubbo,淘宝的Diamond,京东的Hydra,但是当开始了解的时候(比如我接触过的Dubbo)发现他们对各个组件的选择自由度很高,但是如果某一组件出了问题项目就会出现问题(当然高手除外,否则投入的精力成本太高),而SpringCloud在Spring社区下,做了大量的兼容测试,保证了其拥有更好的稳定性,不论其项目的发展目标,还是Spring强大背景,亦或是及其极高的社会活跃度,都是未来企业架构师必须了解和接触到的。
4.SpringCloud简介
SpringCloud是基于SpringBoot实现的微服务架构开发工具。
SpringCloud还包含了很多子项目,如下所述:
·Spring Cloud Config:配置管理工具,支持使用Git存储配置内容,可以使用它实现应用配置的外部化存储,并支持客户端配置信息刷新、加密/解密配置内容等。 ·Spring Cloud Netflix:核心组件,对多个Netflix OSS升源套件进行整合。 _Eureka:服务治理组件,包含服务注册中心、服务注册与发现机制的实现。 -Hystrix:容错管理组件,实现断路器模式,帮助服务依赖中出现的延迟和为故障提供强大的容错能力。 _Ribbon:客户端负载均衡的服务调用组件。 -Feign:基于Ribbon和Hystrix的声明式服务调用组件。 -Zuul:网关组件,提供智能路由、访问过滤等功能。 -Archaius:外部化配置组件。 ·Spring Cloud Bus:事件、消息总线,用于传播集群中的状态变化或事件,以触发后 续的处理,比如用来动态刷新配置等。 ·Spring Cloud Cluster:针对ZooKeeper、Redis、Hazelcast、Consul的选举算法和通用 状态模式的实现。 ·Spring Cloud Cloudfoundry:与Pivotal Cloudfoundry的整合支持。 ·Spring Cloud Consul:服务发现与配置管理工具。 ·Spring Cloud Stream:通过Redis、Rabbit或者Kafka实现的消费微服务,可以通过 简单的声明式模型来发送和接收消息。 ·Spring Cloud AWS:用于简化整合Amazon Web Service的组件。 ·Spring Cloud Security:安全工具包,提供在Zuul代理中对OAuth2客户端请求的中 继器。 ·Spring Cloud Sleuth: Spring Cloud皮用的分布式跟踪实现,可以完美整合Zipkin。 ·Spring Cloud ZooKeeper:基于ZooKeeper的服务发现与配置管理组件。 ·Spring Cloud Starters: Spring Cloud的基础组件,它是基于Spring Boot风格项目的 基础依赖模块。 ·Spring Cloud CLI:用于在Groovy中快速创建Spring Cloud应用的Spring Boot CLI 插件。 |
5.微服务构建
构建maven项目
构建步骤
1.通过官方的SpringInitializr工具来产生基础项目
2.访问http://start.spring.io
3.选择构建工具Maven Project、Spring Boot版本选择1.5.9,填写Group和
Artifact佶息,在Search for dependencies中可以搜索需要的其他依赖包,
这里我们要实现RESTfulAPI,所以可以添加Web依赖。
4.单击Generate Project按钮下载项目压缩包。
5.把压缩包解压后,用Eclipse导入该maven项目。import->Existing Maven Projects
6.项目构建完成
Maven配置解析
<?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>cn.dyc.springcloud</groupId> <artifactId>hello</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>hello</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.9.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project> |
在基础信息部分,groupld和artifactld对应生成项目时页面上输入的内容。另外,我们还可以注意到,打包形式为jar: <packaging>jar</packaging>, Spring Boot默认将该Web应用打包为jar的形式,而非war的形式,因为默认的Web模块依赖会包含嵌入式的Tomcat.这样使得我们的应用jar自身就具备了提供Web服务的能力,后续我们会演示如何启动它。父项目parent配置指定为spring-boot-starter-parent的1.5.9版本,该父项目中定义了Spring Boot版本的基础依赖以及一些默认配置内容,比如,配置文件
application.properties的位置等。
在项目依赖dependencies配置中,包含了下面两项。
.spring-boot-starter-web:全栈Web开发模块,包含嵌入式Tomcat、Spring MVC。
.spring-boot-starter-test:通用测试模块,包含JUnit、Hamcrest、Mockito。
这里所引用的web和test模块,在SpringBoot生态中被称为Starter POMs。StarterPOMs是一系列轻便的依赖包,是一套一站式的Spring相关技术的解决方案。开发者在使用和整合模块时,不必再去搜寻样例代码中的依赖配置来复制使用,只需要引入对应的模块包即可。比如,开发Web应用的时候,就引入spring-boot-starter-web,希望应用具备访问数据库能为的时候,那就再引入spring-boot-starter-j dbc或是更好用的spring-boot-starter-data-jpa。在使用Spring Boot构建应用的时候,各项功能模块的整合不再像传统Spring应用的开发方式那样,需要在pom. xml中做大量的依赖配置
而是通过使用Starter POMs定义的依赖包,使得功能模块整合变得非常轻巧,易于理解与使用。
Spring Boot的Starter POMs采用spring-boot-starter-★的命名方式,★代表一个特别的应用功能模块,比如这里的web、test。Spring Boot工程本身的结构非常简单,大量的学习要点还是将来在对这些Starter POMs的使用之上。项目构建的build部分,引入了Spring Boot的Maven插件,该插件非常实用,可以帮助我们方便地启停应用,这样在开发时就不用每次去找主类或是打包成jar来运行微
服务,只需要通过mvn spring-boot:run命令就可以快速启动Spring Boot应用。
实现RESTfuIAPI
在Spring Boot中创建一个RESTful API的实现代码同Spring MVC应用一样,只是不
需要像Spring MVC那样先做很多配置,而是像下面这样直接开始编写Controller内容:
·新建package,命名为cn.dyc.springcloud.web,可根据实际的构建情况修改成自
己的路径。
·新建HelloController类,内容如下所示。
@RestController public class HelloController { @RequestMapping ( "/hello") public String index() { return "Hello World"; } } 注意事项:要将Application(main类)放在最外层,也就是要包含所有子包。比如你的groupId是cn.dyc.springcloud,子包就是所谓的com.google.xxx,所以要将Application放在cn.dyc.springcloud包下。 请参考以下结论:spring-boot会自动加载启动类所在包下及其子包下的所有组件。 |
单元测试
@RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes = HelloApplication.class) @WebAppConfiguration public class HelloApplicationTests { private MockMvc mvc;
@Before public void setUp(){ mvc = MockMvcBuilders.standaloneSetup(new HelloController()).build(); }
@Test public void hello() throws Exception { mvc.perform(MockMvcRequestBuilders.get("/hello").accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(content().string(equalTo("hello world"))); } } 解析: (1) @RunWith( SpringjUnit4ClassRunner.class):引入Spring对Junit4的支持。 (2) @SpringBootTest(classes = HelloApplication.class):指定Spring Boot的启动类。 (3) @WebAppConfiguration:开启Web应用的配置,用于模拟ServletContext。 (4) MockMvc对象:用于模拟调用Controller的接口发起请求,在@Test定义的hello测试用例中,perform函数执行一次请求调用,accept用于执行接收的数据类型, (5) andExpect用于判断接口返回的期望值。 (6) @Before: JUnit中定义在测试用例@Test内容执行前预加载的内容,这里用来初始化对HelloController的模拟。 (7) 注意引入下面的静态引用,让status. content\ equalTo困数可用: import static org.hamcrest.Matchers.equalTo; import static org. springf ramework. test. web. se rvlet. result. Moc kMvcResultMatchers.content; import static org. springframework. test .web. servlet. result .MockMvcResultMatchers.status; |
多坏境配置
经使得应用的属性在启动前是可变的,所以其中的端口号也好、数据库连接也好,都是可以在应用启动时发生改变的,而不同于以往的Spring应用通过Maven的Profile在编译器中进行不同环境的构建。Spring Boot的这种方式,可以让应用程序的打包内容贯穿开发、测试以及线上部署,而Maven不同Profile的方案为每个环境所构建的包,其内容本质上是不同的。但是,如果每个参数都需要通过命令行来指定,这显然也不是一个好的方案,所以下面我们看看如何在Spring Boot中实现多环境的配置。多环境配置我们在开发应用的时候,通常同一套程序会被应用和安装到几个不同的环境中,比如开发、测试、生产等。其中每个环境的数据库地址、服务器端口等配置都不同,如果在为
不同环境打包时都要频繁修改配置文件的话,那必将是个非常烦琐且容易发生错误的事。对于多环境的配置,各种项目构建工具或是框架的基本思路是一致的,通过配置多份不同环境的配置文件,再通过打包命令指定需要打包的内容之后进行区分打包,Spring Boot
也不例外,或者说实现起来更加简单。
在Spring Boot中,多环境配置的丈件名需要满足application-{profile}.
properties的格式,其中{profile}对应你的环境标识,如下所示。
.application-dev.properties:开发环境。
.application-test.properties:测试环境。
.application-prod.properties:生产环境。
至于具体哪个配置文件会被加载,需要在application .properties文件中通过spring.profiles.active属性来设置,其值对应配置文件中的{profile)值。如spring.profiles .active-test就会加载application-test.properties配置文件内容。
下面,以不同环境配置不同的服务端口为例,进行样例实验。
·针对各环境新建不同的配置文件application-dev.properties、
application-test .properties. application-prod.propertieS
在这三个文件中均设置不同的server.port属性,例如,dev环境设置为Illl,
test坏境设置为2222,prod环境设置为3333。
.application.properties中j发置spring.profiles .active=dev,意为默认以dev环境设置。
·测试不同配置的加载。
加载顺序
Spring Cloud Config是SpringCloud非常重要的一个内容,为了后续能更好地理解Spring CloudConfig的加载机制,我们需要对Spring Boot对数据文件的加载机制有一定的了解。
为了能够更合理地重写各属性的值,Spring Boot使用了下面这种较为特别的属性加载
顺序:
1.在命令行中传入的参数。
2.SPRING APPLICATIONJSON中的属性。SPRING APPLICATION JSON是以JSON格式配置在系统环境变量中的内容。
3.java:comp/env中的JNDI属性。
4.Java的系统属性,可以通过System.getProperties()获得的内容。
5.操作系统的环境变量。
6。通过random.★配置的随机属性。
7.位于当前应用jar包之外,针对不同{profile)环境的配置文件内容,例如application-{ profile).properties或是YAML定义的配置文件。
8.位于当前应用jar包之内,针对不同{profile)环境的配置文件内容,例如application-{ profile).properties或是YAML定义的配置文件。
9.位于当前应用jar包之外的application.properties和YAML配置内容。
10.位于当前应用jar包之内的application.properties和YAML配置内容。
Il.在@Configuration注解修改的类中,通过@PropertySource注解定义的属性。
12.应用默认属性,使用SpringApplication.setDefaultProperties定义的内容。
优先级按上面的顺序由高到低,数字越小优先级越高。
监控与管理
pom文件中增加:
<!-- SpringBoot监控和管理的包(对中小型团队来说比较重要) --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> |
项目启动后,控制台会发现多了很多数据。如:
浏览器访问:/health
最后项目奉上、 ^ _ ^