springcloud-搭建服务注册中心
创建服务注册中心
1.创建一个springboot
命名为eureka-server
1)添加Eureka依赖
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>springcloud</groupId> <artifactId>springcloud-Eureka</artifactId> <version>0.0.1-SNAPSHOT</version> <name>eureka-server</name> <description>a part of the springcloud</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.6.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka-server</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Dalston.SR3</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> </project>
2)启动服务中心
Spring Boot的入口类上添加一个@EnableEurekaServer
注解
2.配置服务注册中心
在application.properties:
server.port=1111 eureka.instance.hostname=localhost #设置该服务注册中心的hostname eureka.client.register-with-eureka=false #默认情况下,这个应用会向注册中心(也是它自己)注册它自己,设置为false表示禁止这种默认行为 eureka.client.fetch-registry=false #表示不去检索其他的服务,因为服务注册中心本身的职责就是维护服务实例,它也不需要去检索其他服务 eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/
注册服务提供者
1.pom
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.sang</groupId> <artifactId>provider</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>provider</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.6.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <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> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Dalston.SR3</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> </project>
2.创建应用入口
@RestController public class HelloController { private final Logger logger = Logger.getLogger(getClass()); @Autowired private DiscoveryClient client; @RequestMapping(value = "/hello", method = RequestMethod.GET) public String index() { List<ServiceInstance> instances = client.getInstances("hello-service"); for (int i = 0; i < instances.size(); i++) { logger.info("/hello,host:" + instances.get(i).getHost() + ",service_id:" + instances.get(i).getServiceId()); } return "Hello World"; } }
3.application
@EnableDiscoveryClient @SpringBootApplication public class ProviderApplication { public static void main(String[] args) { SpringApplication.run(ProviderApplication.class, args); } }
4.配置
spring.application.name=hello-service eureka.client.service-url.defaultZone=http://localhost:1111/eureka
测试
刷新刚才的http://localhost:1111,就能看到注册成功的服务应用了
如果搭建高可用负载均衡?
给eureka-server配置两个application_1.properties,application_2.properties,对应的设置
server.port=1111 eureka.instance.hostname=peer1 eureka.client.register-with-eureka=false eureka.client.fetch-registry=false eureka.client.service-url.defaultZone=http://peer2:1112/eureka/ server.port=1112 eureka.instance.hostname=peer2 eureka.client.register-with-eureka=false eureka.client.fetch-registry=false eureka.client.service-url.defaultZone=http://peer1:1111/eureka/ 1.在peer1的配置文件中,让它的service-url指向peer2,在peer2的配置文件中让它的service-url指向peer1 2.为了让peer1和peer2能够被正确的访问到,我们需要在C:\Windows\System32\drivers\etc目录下的hosts文件总添加两行配置,如下: 127.0.0.1 peer1 127.0.0.1 peer2 3.由于peer1和peer2互相指向对方,实际上我们构建了一个双节点的服务注册中心集群
provider的pom变为
spring.application.name=hello-service eureka.client.service-url.defaultZone=http://peer1:1111/eureka,http://peer2:1112/eureka
负载均衡:生产者消费者
1.服务的发现由Eureka客户端来完成,而服务的消费由Ribbon来完成。Ribbo是一个基于HTTP和TCP的客户端负载均衡器,当我们将Ribbon和Eureka一起使用时,Ribbon会从Eureka注册中心去获取服务端列表,然后进行轮询访问以到达负载均衡的作用,服务端是否在线这些问题则交由Eureka去维护
2.服务springcloud-Eureka-provider生成jar,通过类似代码创建jar,运行后生产者工作结束
java -jar provider-0.0.1-SNAPSHOT.jar --server.port=8080 java -jar provider-0.0.1-SNAPSHOT.jar --server.port=8081
3.创建消费者,Ribbon
1)pom
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.sang</groupId> <artifactId>ribbon-consumer</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>ribbon-consumer</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.6.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <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>Dalston.SR3</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-ribbon</artifactId> </dependency> <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> </dependencies> <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> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
2)配置启动类
@SpringBootApplication @EnableDiscoveryClient//表示该应用是一个Eureka客户端应用,这样该应用就自动具备了发现服务的能力 public class RibbonConsumerApplication { public static void main(String[] args) { SpringApplication.run(RibbonConsumerApplication.class, args); } @LoadBalanced//表示开启客户端负载均衡 @Bean//RestTemplate可以帮助我们发起一个GET或者POST请求 RestTemplate restTemplate() { return new RestTemplate(); } }
3)创建controller
@RestController public class ConsumerController { @Autowired RestTemplate restTemplate; @RequestMapping(value = "/ribbon-consumer",method = RequestMethod.GET) public String helloController() { return restTemplate.getForEntity("http://HELLO-SERVICE/hello", String.class).getBody(); } }
4)application.properties
spring.application.name=ribbon-consumer server.port=9000 eureka.client.service-url.defaultZone=http://localhost:1111/eureka
5)测试
程序运行后,看到服Eurak已有了三个服务,其中消费者服务点开后,访问的url会在8001,8002两个服务提供者中来回调用
注意:
1)服务续约
在注册完服务之后,服务提供者会维护一个心跳来不停的告诉Eureka Server:“我还在运行”,以防止Eureka Server将该服务实例从服务列表中剔除,这个动作称之为服务续约,和服务续约相关的属性有两个,如下:
eureka.instance.lease-expiration-duration-in-seconds=90 eureka.instance.lease-renewal-interval-in-seconds=30
第一个配置用来定义服务失效时间,默认为90秒,第二个用来定义服务续约的间隔时间,默认为30秒。