1.springcloud简介
MicroService(微服务)架构
微服务就是把一个单体项目,拆分为多个微服务,每个微服务可以独立技术选型,独立开发,独立部署,独立运维.并且多个服务相互协调,相互配合,最终完成用户的价值.
Spring cloud是一个基于Spring Boot实现的服务治理工具包,在微服务架构中用于管理和协调服务的。
Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。Spring并没有重复制造轮子,它只是将目前各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过Spring Boot风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。
以下是主要组成部分:
五大神兽:
服务发现——Netflix Eureka
客服端负载均衡——Netflix Ribbon/Feign
服务网关——Netflix Zuul
断路器——Netflix Hystrix
分布式配置——Spring Cloud Config
springcloud与dubbo区别
开始准备注册中心
2.springcloud注册中心Eureka
1,创建一个普通maven工程(父工程)
在其父pom.xml中配置如下依赖
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Finchley.SR1</spring-cloud.version>
<springboot.version>2.0.5.RELEASE</springboot.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${springboot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
2.准备注册中心
创建一个普通的maven子项目springcloud_eureka_7001
在其pom.xml中配置下列的依赖
<dependencies>
<!--springboot支持-->
<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>
</dependency>
<!--Eureka服务端支持-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
在该子模块下的resources目录中创建一个一个application.yml文件
配置内容如下:
server:
port: 7001
eureka:
instance:
hostname: localhost
client:
registerWithEureka: false #是否要注册到eureka
fetchRegistry: false #表示是否从Eureka Server获取注册信息
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #单机配置
在该模块的java目录下准备一个启动类
@SpringBootApplication
@EnableEurekaServer //注册服务中心
public class EurekaServerApp_7001 {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApp_7001.class);
}
}
然后运行,得到如下结果,就说明,你的注册中心已经成功构建了
3.向注册中心(Eureka)注册服务提供者
1.新建一个子模块springcloud_provider_8001
同样在其当前pom.xml中配置如下依赖
<!--服务提供者依赖jar包-->
<dependencies>
<!--公共代码依赖user_interface-->
<dependency>
<groupId>cn.itsource</groupId>
<artifactId>user_interface</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--springboot支持-->
<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>
</dependency>
<!--eureka客户端支持 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
2.配置application.yml文件
server:
port: 8001
spring:
application:
name: USER-PROVIDER #不要使用下划线
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka #告诉服务提供者要把服务注册到哪儿
instance:
prefer-ip-address: true #告诉服务提供者要把服务注册到哪儿
3.启动项和提供的某项具体服务
//启动项
@SpringBootApplication
@EnableEurekaClient
public class UserServerProviderApp_8001 {
public static void main(String[] args) {
SpringApplication.run(UserServerProviderApp_8001.class);
}
}
//某项具体的服务
@RestController
@RequestMapping("/provider")
public class UserController {
@RequestMapping("/user/{id}")
public User getUser(@PathVariable("id") Long id){
return new User(id,"8001provider");
}
}
//我合在一起写的,注意分开
3.分别启动springcloud_eureka_7001和springcloud_provider_8001两个服务
得到如下结果,说明服务注册成功
公共的user_interface说明
user_interface是一个公共的模块,同样也是在父项目中创建一个普通的maven模块的子项目,不需要配置pom.xml
但需要些一个domain实体类在里面,就是一个公共的类,被其他模块调用
//其代码如下,就是一个domain
public class User {
private Long id;
private String name;
public User() {}
public User(Long id, String name) {
this.id = id;
this.name = name;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
其他模块调用的时候,需要配置一个依赖,依赖如下
<!--公共代码依赖-->
<dependency>
<groupId>cn.itsource</groupId>
<artifactId>user_interface</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
4.准备服务消费者
1.同样的在父项目中创建一个子模块springcloud_consumer_9001
在其pom.xml中配置如下依赖
<dependencies>
<!--公共代码依赖-->
<dependency>
<groupId>cn.itsource</groupId>
<artifactId>user_interface</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--springboot支持-->
<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>
</dependency>
</dependencies>
2,同样配置application.yml文件,准备启动类
server:
port: 9001
spring:
application:
name: USER_CONSUMER
@SpringBootApplication
public class UserConsumerApp_9001 {
public static void main(String[] args) {
SpringApplication.run(UserConsumerApp_9001.class);
}
}
准备如下的类
CfgBean
//配置bean
@Configuration
public class CfgBean {
@Bean
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
UserController留意这个路径http://localhost:9001/consumer/user/2
//通过提供服务的路径来访问资源
@RestController
@RequestMapping("/consumer")
public class UserController {
@Autowired
public RestTemplate restTemplate;
@RequestMapping("/user/{id}")
public User getUser(@PathVariable("id") Long id){
String url="http://localhost:8001/provider/user/"+id;
//访问8001
return restTemplate.getForObject(url, User.class);
}
}
5.注册中心(Eureka)集群
1.如果只有一个注册中心,当这个注册中心失效的时候,整个服务就炸了,因此我们需要配置一个注册中心,在某个注册中心失效的时候,依然能够完成注册中心的服务
拷贝,或者准备一个类似的springcloud_eureka_7002我们取名为7002
其他需要修改的都改成7002,
这样,当某个注册中心失效的时候,有另外一给能够顶上,完成注册中心的服务功能
得到如下结果时:
只在一边显示,这是正常情况
6.负载均衡Ribbon
准备一个同样的springcloud_provider_8002
在9001的pom.xml中新增如下依赖
<!--eureka客户端,服务消费者也要从注册中心获取可用服务列表-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--客户端负载均衡实现 ribbon-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
新增注解EnableEurekaClient
开启负载均衡注解LoadBalanced
内置负载均衡规则类
RoundRobinRule(默认)
AvailabilityFilteringRule
WeightedResponseTimeRule
ZoneAvoidanceRule
BestAvailableRule
RandomRule(随机)
Retry
修改负载均衡策略
在config配置类中定义一个方法
@Configuration
public class CfgBean {
@Bean
@LoadBalanced //开启负载均衡策略
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
@Bean //定义负载均衡的随机策略
public IRule myRule(){
return new RandomRule();
}
}
7.负载均衡feign
1.解决参数拼接问题
Feign是以接口方式进行调用,而不是通过RestTemplate来调用,feign底层还是ribbo,它进行了封装,让我们调用起来更加happy.
2,同样的springcloud_consumer_9002复制一份
修改各种配置,这里就不重复了,
//只是这里的注解要多一个扫包的
@SpringBootApplication
@EnableFeignClients(basePackages = "cn.itsource.springcloud.consumer")
public class UserConsumerApp_9002 {
public static void main(String[] args) {
SpringApplication.run(UserConsumerApp_9002.class);
}
}
@RestController
@RequestMapping("/consumer")
public class UserController {
@Autowired
public UserInterface userInterface;
@RequestMapping("/user/{id}")
public User getUser(@PathVariable("id") long id){
return userInterface.getUser(id);
}
}
@FeignClient(value = "USER-PROVIDER")
public interface UserInterface {
@RequestMapping("/provider/user/{id}")
public User getUser(@PathVariable("id") Long id);
}
今天就这些了,五大神兽还有呢!
对了,700是注册中心服务.800服务提供者.900开头是服务消费者,这些概念得清除