Eureka服务注册

·  阅读 71
Eureka服务注册

Eureka服务注册(已停更)

详情介绍就不多说,网上文档官网文档介绍很清楚,这里直接上代码。

创建maven父工程

<!--    重点修改打包方式 pom-->
    <packaging>pom</packaging>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <junit.version>4.12</junit.version>
        <log4j.version>1.2.17</log4j.version>
        <lombok.version>1.16.18</lombok.version>
        <mysql.version>8.0.26</mysql.version>
        <druid.version>1.1.16</druid.version>
        <mybatis.spring.boot.version>1.3.0</mybatis.spring.boot.version>
    </properties>

    <!-- 子模块继承之后,提供作用:锁定版本+子modlue不用写groupId和version  -->
    <dependencyManagement>
        <dependencies>
            <!--spring boot 2.2.2-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.2.2.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--spring cloud Hoxton.SR1-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--spring cloud alibaba 2.1.0.RELEASE-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.1.0.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>${druid.version}</version>
            </dependency>
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>${mybatis.spring.boot.version}</version>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>${junit.version}</version>
            </dependency>
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>${log4j.version}</version>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}</version>
                <optional>true</optional>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <fork>true</fork>
                    <addResources>true</addResources>
                </configuration>
            </plugin>
        </plugins>
    </build>
复制代码

什么不是服务注册?

  • 在父工程中添加两个子工程分别是支付模块cloud-provider-payment8001和客户模块cloud-consumer-order80

  • 支付模块配置

    <artifactId>cloud-provider-payment8001</artifactId>
        <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.10</version>
        </dependency>
        <!--mysql-connector-java-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!--jdbc-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    复制代码

    配置yml

    server:
      port: 8001
    
    spring:
      datasource:
         type: com.alibaba.druid.pool.DruidDataSource            # 当前数据源操作类型
         driver-class-name: com.mysql.cj.jdbc.Driver              # mysql驱动包
         url: jdbc:mysql://localhost:3306/cloud?useUnicode=true&characterEncoding=utf-8&useSSL=false
         username: root
         password: root
    复制代码

    这里新建一个简单数据库就可,一个id,一个name,并配置mapper

     @GetMapping("/payment/get/{id}")
        public Result getPayment(@PathVariable("id") Long id){
            Payment Result = paymentService.getPaymentById(id);
            log.info("******查找结果"+Result+Result);
            if(Result !=  null){
                return new Result(200,"查找成功);
            }
            return new Result(444,"查找失败");
                                  }                
    复制代码

    统一结果返回

    public class Result<T> {
        private Integer code;
        private String message;
        private T      data;
    
        public Result (Integer code,String message){
          this(code,message,null);
        }
    }
    复制代码
  • 客户模块配置

    artifactId>cloud-consumer-order80</artifactId>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-actuator</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-devtools</artifactId>
                <scope>runtime</scope>
                <optional>true</optional>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <optional>true</optional>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>
    复制代码
    server:
      port: 80
    复制代码

    配置RestTemplate,后面会详细解释

    @Configuration
    public class ApplicationContextConfig
    {
        @Bean
        public RestTemplate getRestTemplate()
        {
            RestTemplate restTemplate = new RestTemplate();
            restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));//乱码
            return restTemplate;
        }
    }
    复制代码

    Controller,获得支付模块接口并调用

     private static final String   PAYMENT_URL = "http://localhost:8001";
    
    @GetMapping("/consumer/get/{id}")
        public String getPaymentById(@PathVariable("id") Long id){
            String result = restTemplate.getForObject(PAYMENT_URL+"/payment/get/"+id, String.class);
            return result;
        }
    复制代码
  • 测试

    开启服务测试

eureka1.jpg

成功调用

Eureka服务注册

  • 新建服务注册中心模块cloud-eureka-server7001

     <artifactId>cloud-eureka-server7001</artifactId>
    
        <dependencies>
            <!--eureka-server  这里一定是server表示注册中心-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
            </dependency>
            <!--boot web actuator-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-actuator</artifactId>
            </dependency>
            <!--一般通用配置-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-devtools</artifactId>
                <scope>runtime</scope>
                <optional>true</optional>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
            </dependency>
        </dependencies>
    复制代码

    yml配置

    server:
      port: 7001
    
    eureka:
      instance:
        hostname: eureka7001.com #eureka服务端的实例名称
      client:
        register-with-eureka: false     #false表示不向注册中心注册自己。
        fetch-registry: false     #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
        service-url:
          #单机
         defaultZone: http://eureka7001.com:7001/eureka/
    
    复制代码

    启动类

    @SpringBootApplication
    @EnableEurekaServer //开启服务中心
    public class EurekaServer7001 {
        public static void main(String[] args) {
            SpringApplication.run(EurekaServer7001.class, args);
        }
    }
    
    复制代码
  • 配置服务端与客服端

    pom都新增

      <!--     这里是 client  -->
    <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            </dependency>
    复制代码

    order80配置yml

    spring:
      application:
        name: cloud-order-service
    
    eureka:
      client:
        #表示是否将自己注册进EurekaServer默认为true。
        register-with-eureka: true
        #是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
        fetchRegistry: true
        service-url:
          #单机
        defaultZone: http://localhost:7001/eureka
      instance:
        instance-id: order80
    #    #访问路径可以显示IP地址
        prefer-ip-address: true
    复制代码

    启动类

    @SpringBootApplication
    @EnableEurekaClient  //开启注册
    public class MainOrder80 {
        public static void main(String[] args) {
            SpringApplication.run(MainOrder80.class,args);
        }
    }
    
    复制代码

    payment8001配置是一样的只需要改一下名字

  • 测试

    启动7001-》8001-》80

eureka2.jpg

浏览器输入注册中心地址http://localhost:7001/

查看结果看到相应配置以及被注册进来的消费者生产者

eureka3.jpg 这时候测试80端口接口还是行得通的。

  • 集群

    集群多个注册中心和多个服务业务,那么久多写出一个eureka7002当做集群控制中心,这里如果是在本地电脑操作,就要修改C:\Windows\System32\drivers\etc中hosts文件添加

    127.0.0.1       eureka7002.com
    127.0.0.1       eureka7001.com
    复制代码

    eureka7002配置和eureka7001差不多也可以直接复制修改名字,重点在于这两个注册中心也要互相注册,将指向本身的url指向要集群的url即可。

        service-url:
          #集群指向其它eureka
          defaultZone: http://eureka7002.com:7002/eureka/
    复制代码

    多个支付模块集群配置几乎和payment8001几乎一样,注意点是application-name

    cloud-payment-service ,还有一点就是现在有两个注册中心,需要同时注册进入两个注册中心用逗号隔开就好

       service-url:
          #单机版
    #      defaultZone: http://localhost:7001/eureka
          # 集群版
          defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
    复制代码
  • 测试

eureka7001.jpg

eureka7002.jpg

这时调用80端口查询接口就有不同的效果。更改一下8001,8002Controller代码

 @Value("${server.port}")
    private String port;
 @GetMapping("/payment/get/{id}")
    public Result getPayment(@PathVariable("id") Long id){
        Payment Result = paymentService.getPaymentById(id);
        log.info("******查找结果"+Result+Result+"port"+port);
        if(Result !=  null){
            return new Result(200,"查找成功"+"port"+port,Result);
        }
        return new Result(444,"查找失败"+"port"+port);
    }
复制代码

更改80端口代码,本来80接口是写死查询8001。我们这里要改为注册中心暴露的端口CLOUD-PAYMENT-SERVICE也就是application-name。

//    private static final String   PAYMENT_URL = "http://localhost:8001";
private static final String   PAYMENT_URL = "http://CLOUD-PAYMENT-SERVICE";
复制代码

修改配置类加入@LoadBalanced 赋予RestTemplate负载均衡的能力

@Configuration
public class ApplicationContextConfig
{
    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate()
    {
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
        return restTemplate;
    }
}
复制代码

测试结果,看到结果我们会发现多发送请求就会访问不同的端口。说明我们已经成功了。

eureka80.jpg

eureka802.jpg

总结

  1. 这点对点的遍历中理解很简单,就模块之间的方法调用。但是如果服务很多用户量急剧增加,量变引起质变,怎么去判断有多少提供的服务,有多少客户?

eureka4.jpg

  1. 那就用到eureka服务注册,管理服务于服务之间依赖关系,可以实现服务调用、负载均衡、容错等,实现服务发现与注册。 哪还有一个问题就是注册中心程序崩了怎么办或者服务提供程序崩了怎么办?

eureka5.jpg

  1. 这时就引出的集群概念,试想你的注册中心只有一个only one, 它出故障了那就完犊子谁也不认识谁老死不相往来,会导致整个为服务环境不可用,所以搭建Eureka注册中心集群 ,实现负载均衡+故障容错,而服务提供接口也是这个道理。

  2. 小知识点

  • Eureka自我保护功能eureka.server.enable-self-preservation=true默认开启。

这个功能就是在服务可能停止运行之后不会直接将服务删除,而是默认应该是90秒删除,排除假死的可能。这种情况就相当于人停止心跳大脑不会直接死亡还有抢救的机会,假死现象不能放弃每一个病人。

eviction-interval-timer-in-ms: 2000  //设置假死时间
eureka.server.enable-self-preservation=true//开启关闭
复制代码
  • 发现payment8001、8002中有相同的实体类entities,所以我们将这个相同的实体类拿出来放入一个新模块cloud-api-commons中。

配置pom加入需要的

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.1.0</version>
        </dependency>
    </dependencies>
复制代码

包结构最好和8001、8002一样。将cloud-api-commons通过maven打包。最好是先clean然后install

删除8001/8002中实体类包然后通过maven导入上面打好的包

  <dependency><!-- 引入自己定义的api通用包,可以使用Payment支付Entity -->
            <groupId>com.cloud</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
复制代码

多多指教,QQ1819220754可以交流学习经验

更新

zookeeper
Ribbon
OpenFeign

分类:
后端
标签:
分类:
后端
标签: