Spring Cloud Netflix
SpringCloud是一个基于SpringBoot实现的云应用开发工具,它为基于JVM的云应用开发中的服务发现、断路器、智能路由、微代理、控制总线、全局锁、决策竞选、分布式会话和集群状态管理等操作提供了简单的开发方式。
SpringCloud下包含了多个工程,其中的Spring Cloud Netflix提供了一系列搭建微服务基础架构的功能组件。
Netflix的部分组件及功能特性如下:
Eureka(服务注册与发现框架):一个基于REST风格的服务组件,用于定位服务,以实现云端的负载均衡和中间层服务器的故障转移。
Hystrix(服务容错组件):容错管理工具,旨在通过控制服务和第三方库的节点,从而对延迟和故障提供强大的容村能力。
Zuul(服务网关):边缘服务工具,提供动态路由、监控、贪心、安全等边缘服务。
Ribbon(客户端负载均衡器):提供客户端负载均衡算法,将Netflix的中间层服务连接起来。
Feign(声明式HTTP客户端):可以创建声明式、模板化的HTTP客户端,进行微服务调用。
Eureka服务注册与发现
Eureka介绍
Eureka是一种基于REST的服务,主要用于AWS云中的定位服务,以实现中间层服务器的负载均衡和故障转移。Eureka提供了基于Java的客户端组件,使得与服务的交互更容易。客户端还有一个内置的负载均衡器,用于执行基本的轮训负载均衡。
为什么要用Eureka?
在微服务架构之下,一个微服务可能会在某一时刻进行销毁重建,或是伸缩漂移,这样一来服务实例的网络位置就变得不可预知。为了解决这一问题,我们引入了具有服务注册与发现功能的Eureka。
Eureka架构
Demo
服务端(注册中心)
1.引入pom
注意点:
1)springboot版本要和springcloud的版本对应。
2)如果cloud-netflix jar包引入不进来,增加pom中responsity片段,如下。
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.8.BUILD-SNAPSHOT</version> <relativePath/> <!-- lookup parent from repository --> </parent> <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> <!--eureka server--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Finchley.M8</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> <repositories> <repository> <id>spring-snapshots</id> <name>Spring Snapshots</name> <url>https://repo.spring.io/snapshot</url> <snapshots> <enabled>true</enabled> </snapshots> </repository> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories>
2.启动类
package com.sjp.server; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; @SpringBootApplication @EnableEurekaServer public class ServerApplication { public static void main(String[] args) { SpringApplication.run(ServerApplication.class, args); } }
3.application.yml
注意点:
1)prefer-ip-address:true----允许用ip注册。
2)registerWithEureka: false----避免服务端注册自己。
server: port: 9000 eureka: instance: hostname: 192.168.1.30 prefer-ip-address: true client: registerWithEureka: false fetchRegistry: false serviceUrl: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
4.访问192.168.1.30:9000即可
客户端(注册服务)
1.引入pom,类比与第一个
<!--eureka client--> <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-openfeign</artifactId> </dependency>
2.启动类
package com.sjp; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.openfeign.EnableFeignClients; @SpringBootApplication @EnableDiscoveryClient @EnableFeignClients public class ClientRegistApplication { public static void main(String[] args) { SpringApplication.run(ClientRegistApplication.class, args); } }
3.application.yml
lease-renewal-interval-in-seconds:1---- 每间隔1s,向服务端发送一次心跳,证明自己依然”存活“
lease-expiration-duration-in-seconds:2----- 告诉服务端,如果我2s之内没有给你发心跳,就代表我“死”了,将我踢出掉。
spring: application: name: regist server: port: 9001 eureka: instance: prefer-ip-address: true instance-id: ${spring.application.name}:${server.port} lease-renewal-interval-in-seconds: 1 lease-expiration-duration-in-seconds: 2 client: serviceUrl: defaultZone: http://192.168.1.30:9000/eureka/
4.暴露服务
package com.sjp; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; /** * Created by Timor on 2019/2/20. */ @EnableEurekaClient @RestController public class RegistService { @RequestMapping(value = "/hello", method = RequestMethod.GET) public String hello(@RequestParam("name") String name) { return name + ",Welcome to Springboot!"; } }
客户端(发现服务)
1.pom、启动类一样,application.yml类似(port&ApplicationName)
2.代理的服务
package com.sjp; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; /** * Created by Timor on 2019/2/20. */ @FeignClient(name = "regist") public interface RegistService { @RequestMapping(value = "/hello", method = RequestMethod.GET) public String hello(@RequestParam("name") String name); }
3.测试类
package com.sjp; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; /** * Created by Timor on 2019/2/20. */ @RestController public class Test { @Autowired RegistService registService; @RequestMapping(value = "/hello", method = RequestMethod.GET) public String hello(@RequestParam("name") String name) { return registService.hello(name); } }
4.访问localhost:9001/hello?name=shenjp(原服务)或者localhost:9002/hello?name=shenjp(代理服务)