话不多少,直接开搞
第一步创建maven工程:
依次创建三个module包含:
注册服务中心 springcloud-eureka-server
服务提供者 springcloud-eureka-serversupper
服务消费者 springcloud-eureka-serverconsume
1.创建注册服务中心 springcloud-eureka-server
2.创建服务提供者 springcloud-eureka-serversupper
3. 服务消费者 springcloud-eureka-serverconsume
完整的工程结构,如果不是要重新搭建
注册服务中心 springcloud-eureka-server
提供注册服务的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>org.example</groupId>
<artifactId>springcloud-eureka-server</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
</parent>
<properties>
<junit.version>4.13.1</junit.version>
<lombok.version>1.18.12</lombok.version>
<logback-classic.version>1.2.10</logback-classic.version>
</properties>
<dependencies>
<!--引入springcloud的euekea server依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
<version>2.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.1.3.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
<version>1.3.5.RELEASE</version>
</dependency>
</dependencies>
<!--指定下载源和使用springcloud的版本-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.SR3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
配置application.yml
server:
port: 8700 # 端口自己决定
# 指定当前eureka客户端的注册地址,也就是eureka服务的提供方,当前配置的服务的注册服务方
eureka:
client:
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka
# defaultZone: http://localhost:8698/eureka,http://localhost:8697/eureka
register-with-eureka: false #自身 不在向eureka注册
fetch-registry: false #启动时禁用client的注册
instance:
hostname: localhost
#指定应用名称
spring:
application:
name: eureka-server
创建注册中心启动类EurekaServerApplication
package com.wu;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
/**
* @Author: Gosin
* @Date: 2022/2/11 15:24
*/
@SpringBootApplication
@EnableEurekaServer //当前使用eureka的server
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class,args);
}
}
启动服务 访问http://localhost:8700
配置创建服务提供者 springcloud-eureka-serversupper
与提供注册服务的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>org.example</groupId>
<artifactId>springcloud-eureka-serversupper</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
</parent>
<properties>
<junit.version>4.13.1</junit.version>
<lombok.version>1.18.12</lombok.version>
<logback-classic.version>1.2.10</logback-classic.version>
</properties>
<dependencies>
<!--引入springcloud的euekea server依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>2.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.1.3.RELEASE</version>
<scope>compile</scope>
</dependency>
</dependencies>
<!--指定下载源和使用springcloud的版本-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.SR3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
配置application.yml
server:
port: 8701 # 端口自己决定
# 指定当前eureka客户端的注册地址,
eureka:
client:
service-url:
defaultZone: http://${eureka.instance.hostname}:8700/eureka
instance:
hostname: localhost
#指定应用名称
spring:
application:
name: eureka-server
编写所提供的 服务controller:
package com.wu.controller;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @Author: Gosin
* @Date: 2022/2/11 15:37
*/
@RestController
@RequestMapping("/Hello")
public class EurekaController {
@RequestMapping("/World")
public String helloWorld(@Validated String s){
System.out.println("传入的值为:"+s);
return "传入的值为:"+s;
}
}
创建服务提供者启动类 EurekaServiceApplication
package com.wu;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
/**
* @Author: Gosin
* @Date: 2022/2/11 15:40
*/
@SpringBootApplication
@EnableDiscoveryClient//代表自己是一个服务提供方
public class EurekaServiceApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServiceApplication.class,args);
}
}
访问http://localhost:8700
访问 http://localhost:8701/Hello/World?s=1234
服务消费者 springcloud-eureka-serverconsume
pom.xml配置如下
搭建基于ribbon的客户端,他用于消费服务。
pom中需要在dependencies中添加ribbon依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
完整的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>org.example</groupId>
<artifactId>springcloud-eureka-serverconsume</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
</parent>
<properties>
<junit.version>4.13.1</junit.version>
<lombok.version>1.18.12</lombok.version>
<logback-classic.version>1.2.10</logback-classic.version>
</properties>
<dependencies>
<!--引入springcloud的euekea server依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>2.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.1.3.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
<version>1.3.5.RELEASE</version>
</dependency>
</dependencies>
<!--指定下载源和使用springcloud的版本-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.SR3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
配置application.yml
server:
port: 8702 # 服务消费方
# 指定当前eureka客户端的注册地址,
eureka:
client:
service-url:
defaultZone: http://${eureka.instance.hostname}:8700/eureka
# defaultZone: http://localhost:8697/eureka,http://localhost:8698/eureka,http://localhost:8699/eureka
instance:
hostname: localhost
#当前服务名称
spring:
application:
name: eureka-consumer
消费者工程结构如下图:
我们需要一个controller类来编写ribbon的代码。
package com.wu.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
/**
* @Author: Gosin
* @Date: 2022/2/11 16:07
*/
@RestController
@RequestMapping("/Hello")
public class ConsumerController {
@Autowired
private LoadBalancerClient loadBalancerClient;
@Autowired
private RestTemplate restTemplate;
@RequestMapping("/Consumer")
public String helloWorld(String s){
System.out.println("传入的值为:"+s);
//第一种调用方式
// String forObject = new RestTemplate().getForObject("http://localhost:8071/Hello/World?s=" + s, String.class);
//第二种调用方式
//根据服务名 获取服务列表 根据算法选取某个服务 并访问某个服务的网络位置。
// ServiceInstance serviceInstance = loadBalancerClient.choose("EUREKA-SERVICE");
// String forObject = new RestTemplate().getForObject("http://"+serviceInstance.getHost()+":"+serviceInstance.getPort()+"/Hello/World?s="+s,String.class);
//第三种调用方式 需要restTemplate注入的方式
String forObject = restTemplate.getForObject("http://EUREKA-SERVER/Hello/World?s=" + s, String.class);
return forObject;
}
}
我们常用第三种调用方式。
第一种是直接调用:不经过注册中心那服务列表,直接访问的servicesupport
第二种:是根据服务名选择调用,如上图需要做如下注入
@Autowired
private LoadBalancerClient loadBalancerClient;
如上图代码中第二种调用方法的代码所示。
用服务名去注册中心获取服务列表,当前客户端底层会做随机算法的选取获得服务并访问。
第三种需要一个@Bean的注解自动注入并直接调用restTemplate对象调用服务。底层调用模式与第二种调用方式一样。如下:
package com.wu.beans;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
/**
* @Author: Gosin
* @Date: 2022/2/11 16:09
*/
@Configuration
public class Beans {
//管理简单对象
@Bean
@LoadBalanced
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
@Bean注解告诉工厂,这个方法需要自动注入。
@LoadBalanced,表示需要做负载匀衡。
然后如controller中一样注入一下restTemplate,并且使用他,区别是可以直接使用服务名访问了
//第三种调用方式 需要restTemplate注入的方式
String forObject = restTemplate.getForObject("http://EUREKA-SERVER/Hello/World?s=" + s, String.class);
return forObject;
工程搭建完成,开始测试
启动三个服务
浏览器访问:
访问方法解析:
访问服务消费方@RequestMapping指定的路径及消费方的端口来访问消费方的controllercontroller根据服务名去server方获取获取服务列表,获取服务列表后根据随机的模式负载匀衡后去选择服务地址去访问servicesupport:如下图:
Eureka server的高可用配置
点击配置服务
分别创建三个启动项
配置端口号
VM options: -Dserver.port=8699
VM options: -Dserver.port=8698
VM options: -Dserver.port=8697
最终如上图的排列就OK了
打开springcloud-eureka-server的yml配置,删掉前两行端口号配置
#server:
# port: 8700 # 端口自己决定
# 指定当前eureka客户端的注册地址,也就是eureka服务的提供方,当前配置的服务的注册服务方
eureka:
client:
service-url:
# defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka
defaultZone: http://localhost:8698/eureka,http://localhost:8697/eureka
register-with-eureka: false #自身 不在向eureka注册
fetch-registry: false #启动时禁用client的注册
# instance:
# hostname: localhost
#指定应用名称
spring:
application:
name: eureka-server
注意设置的启动项端口号 不能和配置文件冲突
启动EurekaServerApplication01
启动EurekaServerApplication02
启动EurekaServerApplication03
如图 6个服务全部启动完成
分别访问
打开服务提供方springcloud-eureka-serversupper的yml配置如下,把端口号改为三个中其中的一个。
server:
port: 8701 # 端口自己决定
# 指定当前eureka客户端的注册地址,
eureka:
client:
service-url:
defaultZone: http://${eureka.instance.hostname}:8699/eureka
instance:
hostname: localhost
#指定应用名称
spring:
application:
name: eureka-server
重点:即使服务提供方只注册了一个端口号8699,但是另外两个端口号,也能感知到服务提供方8701的存在了。如下图:
接下来像服务消费方springcloud-eureka-serverconsume中添加服务注册者的端口号,这样在server挂掉任何一个的时候,都能有其他的server也能获取服务列表
server:
port: 8702 # 服务消费方
# 指定当前eureka客户端的注册地址,
eureka:
client:
service-url:
# defaultZone: http://${eureka.instance.hostname}:8700/eureka
defaultZone: http://localhost:8697/eureka,http://localhost:8698/eureka,http://localhost:8699/eureka
instance:
hostname: localhost
#当前服务名称
spring:
application:
name: eureka-consumer
访问以下服务消费方,发现可以通过消费方调用server服务列表并且访问service了
我么随便关闭服务01,02,重启serviceconsume,再进行访问。必须重启serviceconsume才能清空缓存,清掉consume里面有的服务列表。
依然可以正常访问
现在我们关掉所有server后。访问还是没问题,因为缓存了服务列表。
此时重启 springcloud-eureka-serverconsume 无法访问了
至此springcloud中server的高可用配置大功告成