您的位置:首页 > 编程语言 > Java开发

springcloud的入门使用

2019-04-29 19:47 127 查看

1.什么是springcloud
–Spring cloud是一个基于Spring Boot实现的服务治理工具包,在微服务架构中用于管理和协调服务的。它是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。Spring并没有重复制造轮子,它只是将目前各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过Spring Boot风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。
–springcloud的五大神兽:
服务发现——Netflix Eureka
客服端负载均衡——Netflix Ribbon/Feign
服务网关——Netflix Zuul
断路器——Netflix Hystrix
分布式配置——Spring Cloud Config
springcloud主键结构:

2.springcloud的使用
–创建一个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>

3.springcloud–eureka注册中心
原理:

–项目中创建子模块,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>

配置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/ #单机配置

主类,启动器:

@SpringBootApplication
@EnableEurekaServer//标识是eureka服务端
public class EnrekaServerApplication_7001 {
public static void main(String[] args) {
SpringApplication.run(EnrekaServerApplication_7001.class);
}
}

配置完毕之后,根据yml中配置的端口,访问:localhost:7001,进入页面

4.springcloud–provider服务提供者
项目中创建一个子模块:springcloud-provider-8001
子模块pom.xml中配置:

<dependencies>
<!--公共代码依赖-->
<dependency>
<groupId>cn.itsource.springcloud</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>

配置application.yml:

server:
port: 8001
spring:
application:
name: USER-PROVIDER #不要使用下划线
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka #告诉服务提供者要把服务注册到哪儿

入口,启动器:

@SpringBootApplication
@EnableEurekaClient //表示是eureka的客户端
public class UserProviderApplication_8001 {
public static void main(String[] args) {
SpringApplication.run(UserProviderApplication_8001.class);
}
}

Controller层测试:

@RestController
@RequestMapping("/provider")
public class UserController {

//    @Autowired
//    private IUserService userService;
@RequestMapping("/user/{id}") //user/1
public User getUser(@PathVariable("id") Long id) {

// 正常应该调用service获取用户,现在模拟一下
return new User(id, "zs");
}
}

依据路径,访问 http://localhost:8001/provider/user/1 可以得到json数据
5.springcloud–consumer服务消费者
项目中创建一个子模块:springcloud-consumer-9001
配置子模块pom.xml:

<!--公共代码依赖-->
<dependency>
<groupId>cn.itsource.springcloud</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>

配置application.yml

server:
port: 9001
spring:
application:
name: USER_CONSUMER

入口类,启动器:

@SpringBootApplication
public class UserConsumerAppliction_9001 {
public static void main(String[] args) {
SpringApplication.run(UserConsumerAppliction_9001.class);
}
}

需要创建一个工具类,获取RestTemplate对象

@Configuration // <beans></beans>
public class CfgBean {

@Bean //<bean class="org.springframework.web.client.RestTemplate"></bean>
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}

Controller层

@RestController
@RequestMapping("/consumer")
public class UserController {
//多个方法调用只需改一处就ok
public static  final String URL_PREFIX = "http://localhost:8001";
@Autowired
private RestTemplate restTemplate;

@RequestMapping("/user/{id}")
public User getUser(@PathVariable("id")Long id){
//调用远程服务 http请求
String url = URL_PREFIX+"/provider/user/"+id;
return restTemplate.getForObject(url,User.class );
}
}

6.spring注册中心集群
如果只有一个注册中心服务器,会存在单点故障所以要集群,所以可以使用多个注册中心,如果某一个出现了问题,另一个立马替代其功能。
–拷贝一份springcloud-eureka-7002
映射hosts 模拟域名解析 C:\Windows\System32\drivers\etc
127.0.0.1 eureka-7001.com
127.0.0.1 eureka-7002.com
在两个控制中心的application.yml中配置:
springcloud-eureka-7001:

server:
port: 7001
eureka:
instance:
hostname: eureka-7001.com
client:
registerWithEureka: false #是否要注册到eureka
fetchRegistry: false #表示是否从Eureka Server获取注册信息
serviceUrl:
defaultZone: http://eureka-7002.com:7002/eureka/ #集群配置,如果有多个,有逗号分割,不要包含自己

springcloud-eureka-7002:

server:
port: 7002
eureka:
instance:
hostname: eureka-7002.com
client:
registerWithEureka: false #是否要注册到eureka
fetchRegistry: false #表示是否从Eureka Server获取注册信息
serviceUrl:
defaultZone: http://eureka-7001.com:7001/eureka/ #集群配置,如果有多个,有逗号分割,不要包含自己

上述配置,表示调用对方的控制中心
修改springcloud-provider-8001的application.yml的配置,使其接收两个控制中心的管理

server:
port: 8001
spring:
application:
name: user-provider #不要使用下划线
eureka:
client:
service-url:
#defaultZone: http://localhost:7001/eureka #告诉服务提供者要把服务注册到哪儿
defaultZone: http://eureka-7001.com:7001/eureka,http://eureka-7002.com:7002/eureka
instance:
prefer-ip-address: true #显示客户端真实ip

集群配置之后,如果控制中心出现故障,服务提供者依然可以注册到其他的控制中心,而不会出现阻塞现象。
7.负载均衡的实现
为了提供并发量,有时同一个服务提供者可以部署多个。这个客户端在调用时要根据一定的负责均衡策略完成负载调用。
–实现方式一:Ribbon
Ribbon是Netflix发布的云中间层服务开源项目,主要功能是提供客户端负载均衡算法。Ribbon客户端组件提供一系列完善的配置项,如,连接超时,重试等。简单的说,Ribbon是一个客户端负载均衡器,我们可以在配置文件中列出load Balancer后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等)去连接这些机器,我们也很容易使用Ribbon实现自定义的负载均衡算法。
创建一个新的服务提供者:springcloud-provider-8002,并将该服务提供者注册到注册中心
在springcloud-consumer-9001中引入配置:
配置pom.xml

<!--公共代码依赖-->
<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>

<!--客户端负载均衡实现 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>

配置yml:

server:
port: 9001
eureka:
client:
registerWithEureka: false #不注册到Eureka,不在注册中心显示
service-url:
#defaultZone: http://localhost:7001/eureka
defaultZone: http://eureka-7001.com:7001/eureka,http://eureka-7002.com:7002/eureka

新的入口,启动器:

@SpringBootApplication
@EnableEurekaClient
public class UserConsumerApplicaton_9001 {
public static void main(String[] args) {
SpringApplication.run(UserConsumerApplicaton_9001.class);
}
}

在工具类上添加注解,开启负载均衡

@Configuration
public class CfgBean {

@Bean
@LoadBalanced //开启负载均衡
public RestTemplate getRestTemplate(){
return  new RestTemplate();
}
}

Controller层:

@RestController
@RequestMapping("/consumer")
public class UserController {
@Autowired
private RestTemplate restTemplate;

@RequestMapping("/user/{id}")
public User getUser(@PathVariable("id")Long id){
String url = "http://USER-PROVIDER/provider/user/"+id;
return restTemplate.getForObject(url, User.class);
}
}

这样就可以实现,每次访问的时候,能够间隔的访问不同的服务端
–实现方式二:Feign
前面的可以发现当我们通过RestTemplate调用其它服务的API时,所需要的参数须在请求的URL中进行拼接,如果参数少的话或许我们还可以忍受,一旦有多个参数的话,这时拼接请求字符串就会效率低下,并且显得好傻。
Feign是一个声明式的Web Service(RPC框架)客户端,它的目的就是让Web Service调用更加简单。Feign提供了HTTP请求的模板,通过编写简单的接口和插入注解,就可以定义好HTTP请求的参数、格式、地址等信息。而Feign则会完全代理HTTP请求,我们只需要像调用方法一样调用它就可以完成服务请求及相关处理。Feign整合了Ribbon(负载均衡)和Hystrix(断路器)(关于Hystrix我们后面再讲),可以让我们不再需要显式地使用这两个组件。
总起来说,Feign具有如下特性:
1.可插拔的注解支持,包括Feign注解和JAX-RS注解;
2.支持可插拔的HTTP编码器和解码器;
3.支持Hystrix和它的Fallback;
4.支持Ribbon的负载均衡;
5.支持HTTP请求和响应的压缩。
这看起来有点像我们springmvc模式的Controller层的RequestMapping映射。这种模式是我们非常喜欢的。Feign是用@FeignClient来映射服务的。
创建新的服务消费者:springcloud-consumer-9002
配置pom.xml:

<dependencies>
<!--公共代码依赖-->
<dependency>
<groupId>cn.itsource.springcloud</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>

<!--feign的支持-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>

配置yml:

server:
port: 9002
eureka:
client:
registerWithEureka: false #不注册到Eureka,不在注册中心显示
service-url:
#defaultZone: http://localhost:7001/eureka
defaultZone: http://eureka-7001.com:7001/eureka,http://eureka-7002.com:7002/eureka

入口,启动器:

@SpringBootApplication
@EnableFeignClients(basePackages = "cn.itsource")
@EnableEurekaClient
public class UserConsumerApplication_9002 {

public static void main(String[] args) {
SpringApplication.run(UserConsumerApplication_9002.class);
}
}

创建一个接口,用来访问服务提供者的路径,value 表示 服务提供者的yml中name的值

@FeignClient(value = "USER-PROVIDER")
@RequestMapping("/provider")
public interface UserCilent {
@RequestMapping("/user/{id}")
User getUser(@PathVariable("id")Long id);
}

Controller层:

@RestController
@RequestMapping("/consumer")
public class UserController {
@Autowired
private UserCilent userCilent;
@RequestMapping("/user/{id}")
public User getUser(@PathVariable("id")Long id){
return userCilent.getUser(id);
}
}

8.Hystrix断路器
–为什么要使用熔断器?
在理想状态下,一个应用依赖的服务都是健康可用的,我们可以正常的处理所有的请求。当某一个服务出现延迟时,所有的请求都阻塞在依赖的服务,当依赖阻塞时,大多数服务器的线程池就出现阻塞(BLOCK),影响整个线上服务的稳定性,从而导致雪崩现象。在复杂的分布式架构的应用程序有很多的依赖,都会不可避免地在某些时候失败。高并发的依赖失败时如果没有隔离措施,当前应用服务就有被拖垮的风险。
对依赖做隔离,Hystrix就是处理依赖隔离的框架,同时也是可以帮我们做依赖服务的治理和监控.。
当我们使用了Hystrix时,Hystrix将所有的外部调用都封装成一个HystrixCommand或者 HystrixObservableCommand对象,这些外部调用将会在一个独立的线程中运行。我们可以将出现 问题的服务通过熔断、降级等手段隔离开来,这样不影响整个系统的主业务
–熔断器实现方式一,断路器:
添加服务提供者User_provider_hystri8003
配置pom.xml

<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

主类,启动器

@SpringBootApplication
@EnableEurekaClient
@EnableHystrix
public class UserProviderApplication_hystri8003 {
public static void main(String[] args) {
SpringApplication.run(UserProviderApplication_hystri8003.class,args);
}
}

Controller层:

@RestController
@RequestMapping("/provider")
public class UserController {

@RequestMapping("/user/{id}")
@HystrixCommand(fallbackMethod = "failGet")
public User getUser(@PathVariable("id") Long id){
if(id == 2){
throw new RuntimeException("报错啦");
}
return new User(id,"zs_provider222");
}
public User failGet(Long id){
return  new User(id,"用户不存在");
}
}

–熔断器实现方式二,feign:
创建新的服务消费端,User_consumer_fegin_hystri9003
配置yml:

server:
port: 9003
eureka:
client:
registerWithEureka: false #不注册到Eureka,不在注册中心显示
service-url:
defaultZone: http://eureka-7001.com:7001/eureka,http://eureka-7002.com:7002/eureka
feign:
hystrix:
enabled: true #开启熔断支持
client:
config:
remote-service:           #服务名,填写default为所有服务
connectTimeout: 3000
readTimeout: 3000
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 3000

创建一个接口,UserClient:

@FeignClient(value = "USER-PROVIDER",fallback = UserClientFall.class)
public interface UserCilent{

@RequestMapping("/provider/user/{id}")
public User getUser(@PathVariable("id") Long id);

}

创建一个配置接口的实现类

@Component
public class UserClientFall implements UserCilent {
@Override
public User getUser(Long id) {
return new User(id,"用户不存在");
}
}

Controller,通过名字调用服务

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients(basePackages = "cn.itsource.springcloud.fegin")
public class UserConsumerAppliction_9003 {
public static void main(String[] args) {
SpringApplication.run(UserConsumerAppliction_9003.class,args);
}
}

9.Zuul路由网关
–什么是路由网关
Zuul 是netflix开源的一个API Gateway 服务器, 本质上是一个web servlet应用。
Zuul 在云平台上提供动态路由,监控,弹性,安全等边缘服务的框架。Zuul 相当于是设备和 Netflix 流应用的 Web 网站后端所有请求的前门,也要注册入Eureka.
–zuul的使用
创建新的模块zuul_gatewar_9527
配置pom.xml:

<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>

配置application.yml

server:
port: 9527
spring:
application:
name: microservice-zull
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka
zuul:
routes:
user-provider: /user/** #以/user开头的所有路径都转发给user-provider进行处理
ignored-services: "*" #忽略掉服务名访问方式 使用上面/user的方式来访问
prefix: "/services" #添加 前缀访问  localhost:9527/services/user/provider/user/2

主类,启动器:

@SpringBootApplication
@EnableZuulProxy
public class ZuulAppliaction_9527 {

public static void main(String[] args) {
SpringApplication.run(ZuulAppliaction_9527.class);
}
}

10.SpringCloud Config分布式配置中心
–概念
微服务架构中,每个项目都有一个yml配置,管理起来麻烦。要使用spring cloud config来统一管理。
在分布式系统中,由于服务数量巨多,为了方便服务配置文件统一管理,实时更新,所以需要分布式配置中心组件。在Spring Cloud中,有分布式配置中心组件spring cloud config ,它支持配置服务放在配置服务的内存中(即本地),也支持放在远程Git仓库中。在spring cloud config 组件中,分两个角色,一是config server,二是config client。
–使用:
在github中创建配置文件
创建新的模块,配置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-client</artifactId>
</dependency>
<!--配置中心支持-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
</dependencies>

配置yml

server:
port: 6666
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka
instance:
prefer-ip-address: true
spring:
application:
name: spring-cloud-config-server
cloud:
config:
server:
git:
uri: github中配置文件的路径
username: 用户名
password: 密码

主类,启动器:

@SpringBootApplication
@EnableEurekaClient //加入注册中心
@EnableConfigServer //启用配置服务端
public class ConfigServerApplication_6666{
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication_6666.class);
}
}

这样使用之后,github中的配置文件,就加入到了注册中心
–从注册中心读取文件
新建模块config_client_3355
配置pom.xml

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>

配置一个全局的yml,bootstrap.yml

spring:
cloud:
config:
name: application-user #github上面名称
profile: test #环境
label: master #分支
uri: http://localhost:6666 #配置服务器
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka  #告诉服务提供者要把服务注册到哪儿 #单机环境
instance:
prefer-ip-address: true #显示客户端真实ip
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: