首页 资讯 社群 我的社区 搜索

eureka注册中心和微服务之间的调用

LM123
2019-07-03 17:44:49

注册中心

  由于微服务多为集群部署,在这种情况下,微服务之间要调用彼此的接口,如果使用url或者ip地址的形式调用会带来很多麻烦,例如无法确定要连的主机是否可用。在这种情形下,便需要一个系统对所有的微服务进行统一的管理,实时的确定各个微服务所部署的主机的可用状态,这个系统就是注册中心。

  注册中心主要的作用就是统一管理各个微服务,微服务向注册中心注册自己的信息,然后定时的和注册中心通信,以便注册中心区分可用和不可用的主机;而要调用服务的程序则向注册中心申请相应服务,注册中心返回给程序请求服务可用的主机ip以及端口号,这样实现服务的调用,常用的注册中心有eureka,zookeeper等,这里介绍了eureka的使用。

  eureka是springcloud下的一个注册中心,通过它可以实现微服务的统一管理;

eureka的部署:

  首先父工程的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>
    <!--springboot依赖,微服务工程使用springboot构建-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.1.RELEASE</version>
    </parent>
    
    <groupId>cn.ly</groupId>
    <artifactId>ly_cloud_test</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>ly_eureka</module>
        <module>ly_feignribbon_test_server01</module>
        <module>ly_fergnribbon_test_server02</module>
    </modules>
    <properties>
        <okhttp.version>3.9.1</okhttp.version>
        <feign-okhttp.version>8.18.0</feign-okhttp.version>
    </properties>
    <!--依赖管理,对子工程进行相应的依赖版本管理-->
    <dependencyManagement>
        <dependencies>
            <!--springcloud依赖-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Finchley.SR1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--远程调用-->
            <dependency>
                <groupId>com.squareup.okhttp3</groupId>
                <artifactId>okhttp</artifactId>
                <version>${okhttp.version}</version>
            </dependency>
            <dependency>
                <groupId>com.squareup.okhttp3</groupId>
                <artifactId>okhttp</artifactId>
                <version>${okhttp.version}</version>
            </dependency>
            <dependency>
                <groupId>com.netflix.feign</groupId>
                <artifactId>feign-okhttp</artifactId>
                <version>${feign-okhttp.version}</version>
            </dependency>
            
        </dependencies>
    </dependencyManagement>


</project>

然后建立eureka子工程ly_eureka,

引入依赖:

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

配置文件application.yml:

server:
  port: ${PORT:50101} #端口号
spring:
  application:
    name: ly-govern-center #服务名
eureka:
  client:
    register-with-eureka: false #是否向注册中心注册服务
    fetch-registry: false #是否向注册中心发现服务
    serviceUrl:
      defaultZone: http://localhost:50101/eureka/ #注册中心地址,配置多服务器注册中心时需要将多个ip用‘,’分隔
  server:
    enable-self-preservation: false #自我保护设置,当微服务不再报告状态时,也不会立即将其删除,在开发阶段建议设置false
    eviction-interval-timer-in-ms: 60000 #服务注册表清理间隔
  instance:
    hostname: ${EUREKA_DOMAIN:eureka01}

springboot的主函数:

package cn.ly;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer // 声明这是一个eureka的服务器
public class GovernCenterApplication {
    public static void main(String[] args) {
        SpringApplication.run(GovernCenterApplication.class, args);
    }
}

直接启动即可完成eureka注册中心的部署,启动后,在浏览器中输入:localhost:50101看到eureka页面即表明部署成功;

作为一个服务,其本身也是可以集群部署的,只要在配置文件defaultzone中将所有的要部署的ip写上去就行了,中间用逗号隔开;

向eureka中注册服务

服务使用springboot来搭建,创建子工程server01,引入依赖:

<!--向eureka注册服务依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

在主函数上添加注解:

@EnableDiscoveryClient //表明该工程是eureka的客户端,会向eureka注册服务并从中发现服务
提供一个简单的controller:

package cn.ly.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class HelloController {
    int i = 0;
    @ResponseBody
    @RequestMapping("/hello")
    public String hello() {
        i++;
        System.out.println("被调用..."+i);
        return "hello";
    }
}

配置文件application.yml

server:
  port: ${PORT:31001}
spring:
  application:
    name: ly-server01 #服务名,在下面的配置中作为实例名注册到eureka中,其他程序调用服务时需要向eureka提供要调用的实例名,即这个名称
eureka:
  client:
    fetch-registry: true #发现服务
    register-with-eureka: true #注册服务
    service-url:
      defaultZone: ${EUREKA_server:http://localhost:50101/eureka/}  #eureka的地址
  instance:
    prefer-ip-address: true #将自己的IP注册到eureka
    ip-address: ${IP_ADDRESS:127.0.0.1} #注册的ip地址
    instance-id: ${spring.application.name}:${server.port} #注册的实例名称

启动该服务,再次访问localhost:50101,即可看到:

如此,服务便注册成功了。

通过ribbon调用服务

ribbon是一个通过客户端实现负载均衡的系统,它通过服务名向eureka请求可用的服务url,然后通过负载均衡的算法选择一个可用的服务主机进行访问,获得结果;

建立另一个微服务子工程server02,和上述服务一样,需要做成eureka客户端,除此之外,还需要引入额外的依赖:

      <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
      </dependency>

另外,需要配置bean:

@Bean
@LoadBalanced // 这个注解是实现负载均衡的,如果不写的话,就只能直接通过url访问其他服务
public RestTemplate restTemplate() {
    return new RestTemplate(new OkHttp3ClientHttpRequestFactory());
}

配置文件同上面的一致;

另外将上server01工程开上两份,开启时通过设置jvm的参数-DPORT 来设置不同的端口,否则端口会冲突;

通过restTemplate调用hello接口:

@Autowired
RestTemplate restTemplate;
@Test
public void run() {
    for (int i = 0; i < 10; i++) {
    // 直接通过服务名调用接口
        ResponseEntity<String> forEntity = restTemplate.getForEntity("http://ly-server01/hello", String.class);
            String body = forEntity.getBody();
            System.out.println(body);
    }
}

上面调用了hello接口10次,对应于服务端,两个注册服务的服务分别被调用5次,这是因为默认的负载均衡的方式是轮询,也就是依次调用可用的主机;

 

通过feign调用

feign客户端调用远程http接口,可以实现向调用本地接口方法那样调用远程服务,依旧是server02工程调用server01工程的服务;

在server02中添加依赖:

        <!--feign调用-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <dependency>
            <groupId>com.netflix.feign</groupId>
            <artifactId>feign-okhttp</artifactId>
        </dependency>

在主函数上添加注解:@EnableFeignClients

在该工程下创建一个feign接口如下:

package cn.ly.client;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;

@FeignClient("ly-server01") // feign客户端注解,value是要调用的服务名,就是server01工程的服务名
public interface HelloClient {
// 注意一点,如果方法返回的是一个复杂对象类型,那么这个对象类型必须有无参构造器,否则会报错
    @RequestMapping("/hello")
    public String hello();// 这个方法和要调用的服务的接口方法书写要一致,上面的url注意要书写正确且完整,如果被调用的接口的controller类上也有url,那么在这里需要将其补全
}

然后在测试方法中将这个接口注入进去后,即可直接使用方法:

@Autowired
HelloClient helloClient;
@Test
public void run2() {
    for (int i = 0; i < 10; i++) {
        String hello = helloClient.hello();
        System.out.println(hello);
    }
}

上面依旧是调用了10次,分别在两个开启的server01工程中执行5次,轮询的负载均衡;

学习java的新手,尝试将学到的内容总结为博客,内容如有错误,欢迎指正,感激不尽。

用户评论