springcloud之Eureka注册中心与负载均衡实现

Eureka注册中心

1. 认识Eureka

首先我们来解决第一问题,服务的管理。

问题分析

在刚才的案例中,user-service对外提供服务,需要对外暴露自己的地址。而consumer(调用者)需要记录服务提供者的地址。将来地址出现变更,还需要及时更新。这在服务较少的时候并不觉得有什么,但是在现在日益复杂的互联网环境,一个项目肯定会拆分出十几,甚至数十个微服务。此时如果还人为管理地址,不仅开发困难,将来测试、发布上线都会非常麻烦。

Eureka做什么?

Eureka负责管理、记录服务提供者的信息。服务调用者无需自己寻找服务,而是把自己的需求告诉Eureka,然后Eureka会把符合你需求的服务告诉你。

同时,服务提供方与Eureka之间通过“心跳”机制进行监控,当某个服务提供方出现问题,Eureka自然会把它从服务列表中剔除。

这就实现了服务的自动注册、发现、状态监控。

2.原理图

在这里插入图片描述

负载均衡 Ribbon

但是实际环境中,我们往往会开启很多个user-service的集群。此时我们获取的服务列表中就会有多个,到底该访问哪一个呢?

一般这种情况下我们就需要编写负载均衡算法,在多个实例列表中进行选择。

Eureka已经帮我们集成了负载均衡组件 Ribbon,简单修改代码即可使用。

什么是Ribbon:
在这里插入图片描述

代码编写

  • 服务注册中心

    Eureka的服务端应用,提供服务注册和发现功能(Eureka Server 集群)

  • 服务提供者

    提供服务的应用,可以是SpringBoot应用,也可以是其它任意技术实现,只要对外提供的是Rest风格服务即可。(多个提高相同服务的集群)

  • 服务消费者

    消费应用从注册中心获取服务列表,从而得知每个服务方的信息,知道去哪里调用服务方。

1.编写EurekaServer

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">
    <parent>
        <artifactId>spring-cloud-demo</artifactId>
        <groupId>spring-cloud-demo</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>eureka-server</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
    </dependencies>

</project>

启动类:

@SpringBootApplication
@EnableEurekaServer // 告知spring使用EurekaServer
public class EurekaServerApp {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApp.class);
    }
}

配置yml:同一台机器的话实现即可多占用几个端口,多启几个服务实现集群
注意:idea中一个应用不能启动两次。先在edit configuration勾选Allow parallel run。
在这里插入图片描述
使用时我们需要启动一个, 再修改端口, 启动另一个

server:
  port: 10000             # 端口
spring:
  application:
    name: eureka-server   # 应用名称,会在Eureka中显示
eureka:
  client:
    service-url:          # 配置其他Eureka服务的地址;
      defaultZone: http://127.0.0.1:10001/eureka,http://127.0.0.1:10002/eureka

2.将user-service注册到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">
    <parent>
        <artifactId>spring-cloud-parent</artifactId>
        <groupId>spring-cloud-parent</groupId>
        <version>1.0-SNAPSHOT</version>
        <relativePath>../spring-cloud-parent/pom.xml</relativePath>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>user-service</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- Eureka客户端 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
    </dependencies>

</project>

application.yml配置。只有一台机器的话,多开几个端口就开启多个provider服务器,就可以实现某个功能集群(同服务器名称,下方应用名称)。

server:
  port: 9000
spring:
  # 应用名称
  application:
    name: user-service

eureka:
  client:
    service-url:
      # EurekaServer地址:有几台注册几台
      defaultZone: http://127.0.0.1:10000/eureka,http://127.0.0.1:10001/eureka,http://127.0.0.1:10002/eureka
  instance:
    prefer-ip-address: true   # 当调用getHostname获取实例的hostname时,返回ip而不是host名称
    ip-address: 127.0.0.1     # 指定自己的ip信息,不指定的话会自己寻找

启动类

@SpringBootApplication
@EnableDiscoveryClient 		// spring自动查找可用的注册中心(Eureka、zookeeper。。。)
public class UserServiceApp {
    public static void main(String[] args) {
        SpringApplication.run(UserServiceApp.class);
    }
}

Controller层:自定义提供的服务

@RestController
public class UserController {
    @Autowired
    private UserService userService;

    @GetMapping("user/{id}")
    public User queryById(@PathVariable("id") Integer id) {
        return userService.findById(id);
    }
}

3.消费者从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">
    <parent>
        <artifactId>spring-cloud-parent</artifactId>
        <groupId>spring-cloud-parent</groupId>
        <version>1.0-SNAPSHOT</version>
        <relativePath>../spring-cloud-parent/pom.xml</relativePath>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>user-consumer</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        //http客户端工具
        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
            <version>3.14.2</version>
        </dependency>
        //Eureka客户端
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
    </dependencies>

</project>

启动类

@SpringBootApplication
@EnableDiscoveryClient  //开启注册中心客户端
public class CustomerMain {
    public static void main(String[] args) {
        SpringApplication.run(CustomerMain.class);
    }
    //也可以在一个Configure类配置该bean
    @Bean
    @LoadBalanced   //开启负载均衡
    public RestTemplate restTemplate() {
        // 使用okHttp客户端
        return new RestTemplate(new OkHttp3ClientHttpRequestFactory());
    }
}

application.xml 配置

server:
  port: 8080
spring:
  application:
    # 应用名称
    name: user-consumer
eureka:
  client:
    service-url:
      # EurekaServer地址:有几台注册几台
      defaultZone: http://127.0.0.1:10000/eureka,http://127.0.0.1:10001/eureka
  instance:
    prefer-ip-address: true   	# 当其它服务获取地址时提供ip而不是hostname
    ip-address: 127.0.0.1     	# 指定自己的ip信息,不指定的话会自己寻找

user-service:
  ribbon:
     NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

Service层调用服务的方式:直接通过服务名称调用

@Service
public class UserCustomerService {

    @Resource
    private RestTemplate restTemplate;

//这里user-service是服务提供者的注册名称 
//后面的/user/id 是调用服务提供方的provider调用数据的真正uri
//类似于 String url = "http://localhost:8081/user/" + id;
    public User findById(Integer id) {
        String url = "http://user-service/user/" + id;
        return restTemplate.getForObject(url, User.class);
    }
}

配置完毕,直接开启所有Eureka server和service provider ,使用客户端的路径url调用即可。

最后说下,这里server,provider,consumer的pom.xml都继承自一个父pom:通过建空项目,然后建一个maven module而来。该空项目只有一个用于继承的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>spring-cloud-parent</groupId>
    <artifactId>spring-cloud-parent</artifactId>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>../user-service</module>
        <module>../user-consumer</module>
        <module>../eureka-server</module>
    </modules>
    <packaging>pom</packaging>
    <!-- 继承 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.9.RELEASE</version>
    </parent>

    <properties>

    </properties>

    <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>

未完待续。。。。。。。。。。。。。。。。。。先睡觉了

发布了14 篇原创文章 · 获赞 0 · 访问量 308

猜你喜欢

转载自blog.csdn.net/qq_38205881/article/details/104619756