一、认识
1. Monolith(单体应用)架构
在编译时,这些项目将被打包成为一个个JAR包,并最终合并在一起形成一个WAR包。
最终部署的时候只有一份war包,其他的以jar包的方式依赖来.
缺点:在项目很小的情况下这种单体应用比较简单,但是随着项目越变越大,代码越来越多。就会存在以下缺点。
①编译难,部署难,测试难 ②技术选择难 ③扩展难
单体应用中多个模块的负载不均衡,我们扩容高负载的时候,也把低负载的模块也扩容,极大浪费了资源.
2.MicroService(微服务)架构
微服务就是把一个单体项目,拆分为多个微服务,每个微服务可以独立技术选型,独立开发,独立部署,独立运维.并且多个服务相互协调,相互配合,最终完成用户的价值.
优势:
独立部署、技术选型灵活、容错、扩展、
3.springcloud
Spring Cloud是一系列框架的有序集合。
通过Spring Boot风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。
五大神兽:
服务发现——Netflix Eureka
客服端负载均衡——Netflix Ribbon/Feign
服务网关——Netflix Zuul
断路器——Netflix Hystrix
分布式配置——Spring Cloud Config
二、springcloud入门之服务发现
以maven多模块化的方法搭建
1.搭建maven项目 springcloud_parent
1.1.配置pom.xml
1 <!-- 指定版本-->
2 <properties>
3 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
4 <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
5 <java.version>1.8</java.version>
6 <spring-cloud.version>Finchley.SR1</spring-cloud.version>
7 <springboot.version>2.0.5.RELEASE</springboot.version>
8 </properties>
9
10 <dependencyManagement>
11 <dependencies>
12 <dependency>
13 <groupId>org.springframework.cloud</groupId>
14 <artifactId>spring-cloud-dependencies</artifactId>
15 <version>${spring-cloud.version}</version>
16 <type>pom</type>
17 <scope>import</scope>
18 </dependency>
19 <dependency>
20 <groupId>org.springframework.boot</groupId>
21 <artifactId>spring-boot-dependencies</artifactId>
22 <version>${springboot.version}</version>
23 <type>pom</type>
24 <scope>import</scope>
25 </dependency>
26 </dependencies>
27 </dependencyManagement>
2.单机注册中心搭建 springcloud_eureka_7001
2.1配置pom.xml
1 <dependencies>
2 <!--springboot支持-->
3 <dependency>
4 <groupId>org.springframework.boot</groupId>
5 <artifactId>spring-boot-starter-web</artifactId>
6 </dependency>
7 <dependency>
8 <groupId>org.springframework.boot</groupId>
9 <artifactId>spring-boot-starter-test</artifactId>
10 </dependency>
11
12 <!--Eureka服务端支持-->
13 <dependency>
14 <groupId>org.springframework.cloud</groupId>
15 <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
16 </dependency>
17 </dependencies>
2.2 配置application.yml
1 server:
2 port: 7001
3 eureka:
4 instance:
5 hostname:
6 client:
7 registerWithEureka: false #作为一个注册中心不需要注册自己是否要注册到eureka
8 fetchRegistry: false #表示是否从Eureka Server获取注册信息
9 serviceUrl:
10 #defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #单机配置
11 defaultZone: http://:7002/eureka/ #集群配置,如果有多个,有逗号分割,不要包含自己1
2.3启动项
1 @SpringBootApplication
2 @EnableEurekaServer//标识注册中心
3 public class EurekaServerApp_7001 {
4 public static void main(String[] args) {
5 SpringApplication.run(EurekaServerApp_7001.class);
6 }
7 }
2.4效果图 访问 localhost:7001
Eureka Server 在运行期间会去统计心跳失败比例在 15 分钟之内是否低于 85%,如果低于 85%,Eureka Server 会将这些实例保护起来,让这些实例不会过期,但是在保护期内如果服务刚好这个服务提供者非正常下线了,此时服务消费者就会拿到一个无效的服务实例,此时会调用失败,对于这个问题需要服务消费者端要有一些容错机制,如重试,断路器等。
3.服务提供者 springcloud_provider_8001
3.1配置pom.xml
1 <dependencies>
2 <!--公共代码依赖-->
3 <dependency>
4 <groupId>cn.su</groupId>
5 <artifactId>user_interface</artifactId>
6 <version>1.0-SNAPSHOT</version>
7 </dependency>
8
9 <!--springboot支持-->
10 <dependency>
11 <groupId>org.springframework.boot</groupId>
12 <artifactId>spring-boot-starter-web</artifactId>
13 </dependency>
14 <dependency>
15 <groupId>org.springframework.boot</groupId>
16 <artifactId>spring-boot-starter-test</artifactId>
17 </dependency>
18
19 <!--eureka客户端支持 -->
20 <dependency>
21 <groupId>org.springframework.cloud</groupId>
22 <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
23 </dependency>
24 </dependencies>
3.2 配置 application.yml
1 server:
2 port: 8001
3 spring:
4 application:
5 name: USER-PROVIDER #不要使用下划线
6 eureka:
7 client:
8 service-url:
9 defaultZone: http://:7001/eureka,http://:7002/eureka
10 #defaultZone: http://localhost:7001/eureka
11 instance:
12 prefer-ip-address: true #告诉服务提供者要把服务注册到哪儿
3.3 配置提供者服务方法 UserController
1 @RestController
2 @RequestMapping("/provider")
3 public class UserController {
4
5 @RequestMapping("/user/{id}")
6 public User getUser(@PathVariable("id") Long id) {
7 return new User(id, "8001su");
8 }
9 }
3.4启动项
1 @SpringBootApplication
2 @EnableEurekaClient
3 public class UserServerProviderApp_8001 {
4
5 public static void main(String[] args) {
6 SpringApplication.run(UserServerProviderApp_8001.class);
7 }
8 }
3.5 效果图
4.服务消费者 springcloud_consumer_9001
4.1准备domain模块 user_interface
1 public class User {
2 private Long id;
3 private String name;
4
5 //省略构造器和get、set
6 }
4.2配置pom.xml
1 <dependencies>
2 <!--公共代码依赖-->
3 <dependency>
4 <groupId>cn.su</groupId>
5 <artifactId>user_interface</artifactId>
6 <version>1.0-SNAPSHOT</version>
7 </dependency>
8
9 <!--springboot支持-->
10 <dependency>
11 <groupId>org.springframework.boot</groupId>
12 <artifactId>spring-boot-starter-web</artifactId>
13 </dependency>
14 <dependency>
15 <groupId>org.springframework.boot</groupId>
16 <artifactId>spring-boot-starter-test</artifactId>
17 </dependency>
18 <!--eureka客户端,服务消费者也要从注册中心获取可用服务列表-->
19 <dependency>
20 <groupId>org.springframework.cloud</groupId>
21 <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
22 </dependency>
23 <!--客户端负载均衡实现 ribbon-->
24 <dependency>
25 <groupId>org.springframework.cloud</groupId>
26 <artifactId>spring-cloud-starter-ribbon</artifactId>
27 </dependency>
28 <dependency>
29 <groupId>org.springframework.cloud</groupId>
30 <artifactId>spring-cloud-starter-config</artifactId>
31 </dependency>
32 </dependencies>
4.3 配置application.yml
1 server:
2 port: 9001
3 spring:
4 application:
5 name: USER_CONSUMER
6 eureka:
7 client:
8 registerWithEureka: false #不注册到Eureka,不在注册中心显示
9 service-url:
10 #defaultZone: http://localhost:7001/eureka
11 defaultZone: http://:7001/eureka,http://:7002/eureka
4.4配置类
1 @Configuration
2 public class CfgBean {
3
4 @Bean
5 public RestTemplate getRestTemplate(){
6 return new RestTemplate();
7 }
8 }
4.5userController
1 @RestController
2 @RequestMapping("/consumer")
3 public class UserController {
4
5 @Autowired
6 private RestTemplate restTemplate;
7
8 @RequestMapping("/user/{id}")
9 public User getUser(@PathVariable("id") Long id){
10 String url="http://localhost:8001/provider/user/"+id;
11 //String url="http://USER-PROVIDER/provider/user/"+id;
12 return restTemplate.getForObject(url, User.class);
13 }
14 }
4.6启动项
1 @SpringBootApplication
2 @EnableEurekaClient
3 public class UserConsumerApp_9001 {
4 public static void main(String[] args) {
5 SpringApplication.run(UserConsumerApp_9001.class);
6 }
7 }
4.5效果图
三、springcloud 入门之 负载均衡
方法一:客户端负载均衡实现 ribbon
1.1写一个类配置负载均衡
1 @Configuration
2 public class CfgBean {
3
4 @Bean
5 @LoadBalanced//负载均衡 轮循
6 public RestTemplate getRestTemplate(){
7 return new RestTemplate();
8 }
9
10 //负载均衡配置
11 @Bean
12 public IRule myRule(){
13 return new RandomRule();//随机算法替换轮训
14 }
15 }
1.2 userController
1 @RestController
2 @RequestMapping("/consumer")
3 public class UserController {
4
5 @Autowired
6 private RestTemplate restTemplate;
7
8 @RequestMapping("/user/{id}")
9 public User getUser(@PathVariable("id") Long id){
10 //String url="http://localhost:8001/provider/user/"+id;
11 String url="http://USER-PROVIDER/provider/user/"+id;
12 return restTemplate.getForObject(url, User.class);
13 }
14 }
方法二:feign
2.1创建maven模块 springcloud_consumer_9002
2.2.配置pom.xml
1 <dependencies>
2 <!--公共代码依赖-->
3 <dependency>
4 <groupId>cn.su</groupId>
5 <artifactId>user_interface</artifactId>
6 <version>1.0-SNAPSHOT</version>
7 </dependency>
8
9 <!--springboot支持-->
10 <dependency>
11 <groupId>org.springframework.boot</groupId>
12 <artifactId>spring-boot-starter-web</artifactId>
13 </dependency>
14 <dependency>
15 <groupId>org.springframework.boot</groupId>
16 <artifactId>spring-boot-starter-test</artifactId>
17 </dependency>
18
19 <!--eureka客户端,服务消费者也要从注册中心获取可用服务列表-->
20 <dependency>
21 <groupId>org.springframework.cloud</groupId>
22 <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
23 </dependency>
24
25 <!--feign的支持-->
26 <dependency>
27 <groupId>org.springframework.cloud</groupId>
28 <artifactId>spring-cloud-starter-openfeign</artifactId>
29 </dependency>
30 </dependencies>
2.3.配置application.yml
1 server:
2 port: 9002
3 spring:
4 application:
5 name: USER_CONSUMER
6 eureka:
7 client:
8 registerWithEureka: false #不注册到Eureka,不在注册中心显示
9 service-url:
10 #defaultZone: http://localhost:7001/eureka
11 defaultZone: http://:7001/eureka,http://:7002/eureka
2.4配置接口 UserInterface实现负载均衡
1 @FeignClient(value = "USER-PROVIDER")
2 @RequestMapping("/provider")
3 public interface UserInterface {
4
5 @RequestMapping("/user/{id}")
6 public User gertUser(@PathVariable("id") Long id);
7 }
2.5写userController
1 @RestController
2 @RequestMapping("/consumer")
3 public class UserController {
4
5 @Autowired
6 private UserInterface userInterface;
7
8 @RequestMapping("/user/{id}")
9 public User getUser(@PathVariable("id") Long id){
10 System.out.println(userInterface.getClass());
11 return userInterface.gertUser(id);
12 }
13 }
2.6启动项 注意需要扫描
1 @SpringBootApplication
2 @EnableFeignClients(basePackages ="cn.su.feign")
3 public class UserConsumerApp_9002 {
4 public static void main(String[] args) {
5 SpringApplication.run(UserConsumerApp_9002.class);
6 }
7 }