三、Eureka服务注册中心

目录

  • 前言
  • 一、Eureka介绍
  • 二、构建EurekaServer端
  • 三、构建EurekaClient端-producer
  • 四、构建EurekaClient端-consumer
  • 五、服务剔除测试(集群)

前言

  • 上一节中我们介绍了服务治理并使用HttpClient实现了RPC远程调用
  • 但是还存问题,如果生产者的ip和端口号改变,消费者的代码就势必要进行修改
  • 本节我们将介绍Eureka服务注册中心来解决该问题

一、Eureka介绍

  • 1.Eureka是什么
    • Euraka是Spring Cloud集合中一个组件,它是对Euraka的集成,用于服务注册和发现
  • 2.Eureka组成
    • Eureka由多个instance(服务实例)组成,这些服务实例可以分为两种:Eureka Server和Eureka Client。为了便于理解,我们将Eureka client再分为Service Provider和Service Consumer。
      • Eureka Server:提供服务注册和发现
      • Service Provider:服务提供方,将自身服务注册到Eureka,从而使服务消费方能够找到
      • Service Consumer:服务消费方,从Eureka获取注册服务列表,从而能够消费服务

二、构建EurekaServer端

  • 1.新建项目spring-cloud-eureka-server
  • 2.pom依赖
<dependencies>
    <dependency>
        <groupId>org.springframework.cloudgroupId>
        <artifactId>spring-cloud-starter-netflix-eureka-serverartifactId>
    dependency>
dependencies>
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-dependenciesartifactId>
            <version>Finchley.RC2version>
            <type>pomtype>
            <scope>importscope>
        dependency>
    dependencies>
dependencyManagement>
<repositories>
    <repository>
        <id>spring-milestonesid>
        <name>Spring Milestonesname>
        <url>https://repo.spring.io/milestoneurl>
        <snapshots>
            <enabled>falseenabled>
        snapshots>
    repository>
repositories>

  • 3.application.yml
server:
  port: 9090 #服务注册中心端口号
spring:
  application:
    name: spring-cloud-eureka-server
eureka:
  instance:
    hostname: 127.0.0.1 #服务注册中心IP地址
  client:
    registerWithEureka: false #是否向服务注册中心注册自己
    fetchRegistry: false #是否检索服务
    serviceUrl: #服务注册中心的配置内容,指定服务注册中心的位置
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
  • 4.AppEurekaServer
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer
public class AppEurekaServer {
    public static void main(String[] args) {
        SpringApplication.run(AppEurekaServer.class);
    }
}
  • 5.验证Eureka是否启动成功
    • 访问地址:http://127.0.0.1:9090/
    • 若出现如下界面,说明EurekaServer端启动成功了

三、Eureka服务注册中心_第1张图片

三、构建EurekaClient端-producer

  • 1.新建项目spring-cloud-eureka-client-producer
  • 2.pom依赖
<dependencies>
    <dependency>
        <groupId>org.springframework.cloudgroupId>
        <artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
    dependency>
dependencies>
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-dependenciesartifactId>
            <version>Finchley.RC2version>
            <type>pomtype>
            <scope>importscope>
        dependency>
    dependencies>
dependencyManagement>

<repositories>
    <repository>
        <id>spring-milestonesid>
        <name>Spring Milestonesname>
        <url>https://repo.spring.io/milestoneurl>
        <snapshots>
            <enabled>falseenabled>
        snapshots>
    repository>
repositories>
  • 2.application.yml
server:
  port: 7070
spring:
  application:
    name: sjyl-producer-member #服务名称,在注册中心展示服务名称
eureka:
  client:
    serviceUrl: #服务注册中心接口地址
      defaultZone: http://127.0.0.1:9090/eureka/
  • 3.新增MemberService
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MemberService {

    /**
     * 会员服务提供接口
     */
    @RequestMapping("/getMember")
    public String getMember() {
        return "我是会员服务,我提供接口";
    }
}
  • 4.AppProducer
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;


@SpringBootApplication
@EnableEurekaClient
public class AppProducer {
    public static void main(String[] args) {
        SpringApplication.run(AppProducer.class);
    }
}
  • 5.启动producer后访问Eureka
    • 访问地址:http://127.0.0.1:9090/

三、Eureka服务注册中心_第2张图片

四、构建EurekaClient端-consumer

  • 1.新建项目spring-cloud-eureka-client-consumer
  • 2.pom依赖

    <dependencies>
        <dependency>
            <groupId>org.apache.httpcomponentsgroupId>
            <artifactId>httpclientartifactId>
            <version>4.5.5version>
        dependency>
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
        dependency>
    dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloudgroupId>
                <artifactId>spring-cloud-dependenciesartifactId>
                <version>Finchley.RC2version>
                <type>pomtype>
                <scope>importscope>
            dependency>
        dependencies>
    dependencyManagement>

    <repositories>
        <repository>
            <id>spring-milestonesid>
            <name>Spring Milestonesname>
            <url>https://repo.spring.io/milestoneurl>
            <snapshots>
                <enabled>falseenabled>
            snapshots>
        repository>
    repositories>
 
  • 3.application.yml
server:
  port: 8080
spring:
  application:
    name: sjyl-consumer-order #服务名称,在注册中心展示服务名称
eureka:
  client:
    serviceUrl: #服务注册中心接口地址
      defaultZone: http://127.0.0.1:9090/eureka/
  • 4.工具类HttpClientUtils
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;


public class HttpClientUtils {

    private static final CloseableHttpClient httpClient;
    public static final String CHARSET = "UTF-8";
    private static final Log log = LogFactory.getLog(HttpClientUtils.class);

    // 采用静态代码块,初始化超时时间配置,再根据配置生成默认httpClient对象
    static {
        RequestConfig config = RequestConfig.custom().setConnectTimeout(60000).setSocketTimeout(15000).build();
        httpClient = HttpClientBuilder.create().setDefaultRequestConfig(config).build();
    }

    public static String doGet(String url, Map<String, String> params) {
        return doGet(url, params, CHARSET);
    }


    public static String doPost(String url, Map<String, String> params) throws IOException {
        return doPost(url, params, CHARSET);
    }

    /**
     * HTTP Get 获取内容
     *
     * @param url     请求的url地址 ?之前的地址
     * @param params  请求的参数
     * @param charset 编码格式
     * @return 页面内容
     */
    public static String doGet(String url, Map<String, String> params, String charset) {
        try {
            if (params != null && !params.isEmpty()) {
                List<NameValuePair> pairs = new ArrayList<NameValuePair>(params.size());
                for (Map.Entry<String, String> entry : params.entrySet()) {
                    String value = entry.getValue();
                    if (value != null) {
                        pairs.add(new BasicNameValuePair(entry.getKey(), value));
                    }
                }
                // 将请求参数和url进行拼接
                url += "?" + EntityUtils.toString(new UrlEncodedFormEntity(pairs, charset));
            }
            HttpGet httpGet = new HttpGet(url);
            CloseableHttpResponse response = httpClient.execute(httpGet);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != 200) {
                httpGet.abort();
                throw new RuntimeException("HttpClient,error status code :" + statusCode);
            }
            HttpEntity entity = response.getEntity();
            String result = null;
            if (entity != null) {
                result = EntityUtils.toString(entity, "utf-8");
            }
            EntityUtils.consume(entity);
            response.close();
            return result;
        } catch (Exception e) {
            log.error("请求服务器端出错:" + e);
            return null;
        }

    }

    /**
     * HTTP Post 获取内容
     *
     * @param url     请求的url地址 ?之前的地址
     * @param params  请求的参数
     * @param charset 编码格式
     * @return 页面内容
     * @throws IOException
     */
    public static String doPost(String url, Map<String, String> params, String charset)
            throws IOException {
        List<NameValuePair> pairs = null;
        if (params != null && !params.isEmpty()) {
            pairs = new ArrayList<NameValuePair>(params.size());
            for (Map.Entry<String, String> entry : params.entrySet()) {
                String value = entry.getValue();
                if (value != null) {
                    pairs.add(new BasicNameValuePair(entry.getKey(), value));
                }
            }
        }
        HttpPost httpPost = new HttpPost(url);
        if (pairs != null && pairs.size() > 0) {
            httpPost.setEntity(new UrlEncodedFormEntity(pairs, CHARSET));
        }
        CloseableHttpResponse response = null;
        try {
            response = httpClient.execute(httpPost);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != 200) {
                httpPost.abort();
                throw new RuntimeException("HttpClient,error status code :" + statusCode);
            }
            HttpEntity entity = response.getEntity();
            String result = null;
            if (entity != null) {
                result = EntityUtils.toString(entity, "utf-8");
            }
            EntityUtils.consume(entity);
            return result;
        } catch (ParseException e) {
            log.error("请求服务器端出错:" + e);
            return null;
        } finally {
            if (response != null)
                response.close();
        }
    }
}


  • 5.OrderToMemberService
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class OrderToMemberService {

    @Autowired
    private DiscoveryClient discoveryClient;

    @RequestMapping("/orderToMember")
    public String orderToMember() {
        /**
         * 根据服务名称 从注册中心 获取 会员的接口地址
         * 服务提供 启动多个集群
         *
         */
        List<ServiceInstance> instances = discoveryClient.getInstances("sjyl-member");
        ServiceInstance serviceInstance = instances.get(0);
        // 会员服务的ip和端口
        String memberUrl = "http://" + serviceInstance.getHost() + ":" + serviceInstance.getPort() + "/" + "getMember";
        return "订单服务调用会员服务:" + HttpClientUtils.doGet(memberUrl, null);
    }
}
  • 6.消费者启动类AppConsumer
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient
public class AppConsumer {
    public static void main(String[] args) {
        SpringApplication.run(AppConsumer.class);
    }
}
  • 7.Eureka注册中心
    • 访问地址:http://127.0.0.1:9090/

三、Eureka服务注册中心_第3张图片

  • 8.测试
    • 访问地址:http://127.0.0.1:8080/orderToMember

三、Eureka服务注册中心_第4张图片

五、服务剔除测试(集群)

  • 1.spring-cloud-eureka-client-producer中新增启动类AppProducer2
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;


@SpringBootApplication
@EnableEurekaClient
public class AppProducer2 {
    public static void main(String[] args) {
        SpringApplication.run(AppProducer2.class);
    }
}
  • 2.application.yml修改下端口号为7071
server:
  port: 7071
spring:
  application:
    name: sjyl-producer-member #服务名称,在注册中心展示服务名称
eureka:
  client:
    serviceUrl: #服务注册中心接口地址
      defaultZone: http://127.0.0.1:9090/eureka/
  • 3.启动AppProducer2访问Dureka
    • 访问地址:http://127.0.0.1:9090/
    • 可以看到Producer有2个,这个也是模拟集群测试

三、Eureka服务注册中心_第5张图片

  • 4.修改spring-cloud-eureka-client-consumer的orderToMember
    • 增加端口打印后,重新启动AppConsumer
import com.sjyl.util.HttpClientUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class OrderToMemberService {

    @Autowired
    private DiscoveryClient discoveryClient;

    @RequestMapping("/orderToMember")
    public String orderToMember() {
        /*
         * 根据服务名称 从注册中心 获取 会员的接口地址
         * 服务提供 启动多个集群
         *
         */
        List<ServiceInstance> instances = discoveryClient.getInstances("sjyl-producer-member");
        ServiceInstance serviceInstance = instances.get(0);
        // 会员服务的ip和端口
        String memberUrl = "http://" + serviceInstance.getHost() + ":" + serviceInstance.getPort() + "/" + "getMember";
        return "port=" + serviceInstance.getPort() + "  订单服务调用会员服务:" + HttpClientUtils.doGet(memberUrl, null);
    }
}
  • 5.测试1:AppProducer和AppProducer2同时开启
    • 访问:http://127.0.0.1:8080/orderToMember

三、Eureka服务注册中心_第6张图片

  • 6.测试2:关闭AppProducer,只开启AppProducer2
    • 稍等一会后,Eureka会自动将AppProducer剔除,即7070端口的生产者服务剔除
    • 访问:http://127.0.0.1:8080/orderToMember

三、Eureka服务注册中心_第7张图片

你可能感兴趣的:(SpringCloud快速入门,spring,boot,spring,java,微服务,架构)