springcloud的入门使用
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
- SpringCloud使用Consul做服务发现入门
- SpringCloud自学入门-RestTemplate的使用
- 手把手教你ARC——ARC入门和使用
- Windows Azure入门教学系列 (四):使用Blob Storage
- Python使用MONGODB入门实例
- jQuery入门及选择器使用
- 在.Net Core中使用MongoDB的入门教程(一)
- XSL 语言入门2 -- 使用XSLT将XML转换为(X)HTML
- COM编程入门:第一部分 什么是COM,如何使用COM
- 【Swing入门教程】一步一步做Netbeans(4):JTree的使用及定制TreeCellRenderer
- springcloud 入门 3 (服务之间的调用)
- Git使用入门,使用原理解读及如何在GitLab、GitHub或者Stash上管理项目(三)
- Android注解使用快速入门
- javascript使用正则表达式入门
- Delphi DataSnap 初步入门使用总结
- pdf.js 入门使用指南3-字体显示问题
- Gradle 入门使用(1)
- Android Volley入门到精通:使用Volley加载网络图片
- Validform使用入门
- Python的SQLAlchemy框架使用入门