微服务|springcloud系列之-15分钟快速了解eureka及实战

目录

摘要

eureka简介

eureka实战

服务注册中心开发

服务生产者开发

服务消费者开发

实现高可用的eureka

zookeeper与eureka的区别

有关eureka面试题及解答

总结


摘要

我们不管在进行分布式开发还是微服务开发,都需要接触一个组件,那就是服务治理中心,必须有一个组件为你提供和发现服务的功能,注册中心可以由zookeeper、reids、eureka等框架担任,因为我们这个系列主讲springcloud,所以本篇文章主要介绍eureka组件,后面也会论述这几种注册中心的区别。

eureka简介

spring cloud eureka是 基于netflix eureka的二次封装,主要负责实现微服务架构中的服务治理功能,springcloud eureka是基于http协议上的rest通信方式,并且提供了对应的客户端组件,能够非常方便的进行服务治理。服务治理必须要要有一个注册中心,除了使用eureka作为注册中心,还可以使用zookeeper作为注册中心,阿里开源的dubbo框架就可以支持zookeeper作为注册中心,使用过dubbo的人,都知道dubbo除了提供zookeeper作为注册中心,还可以支持redis等框架作为注册中心。刚接触微服务或者分布式的人可能还不知道什么叫做服务注册中心,我简单给大家描述下,大家可以看下这张图

上图描述注册中心的主要功能,生产者既可以提供服务又可以作为消费者去向注册中心请求服务。如果大家对注册中心还不是很了解的话,那就看下图:

eureka实战

开发工具:IDEA ,jdk版本:1.8 maven 3.5.4

服务注册中心开发

1.创建一个空项目,命名为springcloud-blog

打开项目后,添加新的模块

2.添加新模块

一直点击next,创建项目完成

3.添加依赖,为了保证后面操作一致性,建议复制以下依赖到pom文件中

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Finchley.SR2</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </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>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

4.开启eureka服务治理功能

添加@EnableEurekaServe注解开启
@SpringBootApplication
//开启服务治理功能
@EnableEurekaServer
public class EurekaServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class, args);
    }
}

5.集成security框架,实现eureka安全认证

添加如下配置类

@EnableWebSecurity
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable();
        http.authorizeRequests()
                .anyRequest()
                .authenticated()
                .and()
                .httpBasic();
    }
}

6.编辑配置文件

默认使用idea 创建的springboot项目,生成的配置文件是application.properties,建议使用yml格式,更加简洁明了,直接修改后缀名application.yml

将如下内容贴入

spring:
  application:
# 服务名
    name: eureka-server
# security安全认证配置
  security:
    user:
      name: yangle
      password: 123
server:
  port: 8761
eureka:
  client:
#  该应用为注册中心,不需要向注册中心注册自己
    register-with-eureka: false
#    关闭检索服务的功能,只需要维护服务
    fetch-registry: false

7.运行main方法,启动eureka

8.启动后test里面会报错

我们把这一行删除,然后重新导test包即可

9.项目启动后,访问http://localhost:8761/,输入用户名和密码 yangle  123

看到上面的页面,代表eureka已经启动成功,接下来我们开发服务生产者

服务生产者开发

1.创建springboot项目

项目建好之后发现右下角有提示点击show,后续就可以方便启动springboot项目了

2.复制依赖


    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Finchley.SR2</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

3.开启服务发现功能,编辑application文件,添加

@EnableDiscoveryClient

@SpringBootApplication
//开启服务发现功能
@EnableDiscoveryClient
public class EurekaClientProducterApplication {

    public static void main(String[] args) {
        SpringApplication.run(EurekaClientProducterApplication.class, args);
    }

}

4.和前面一样,更改配置文件后缀名为yml,并复制以下内容

spring:
  application:
    name: eureka-client-order-service
server:
  port: 8081
eureka:
  client:
    serviceUrl:
#    指定注册中心
      defaultZone: http://yangle:123@localhost:8761/eureka
  instance:
#可选
    preferIpAddress: true
#实例ID支持自定义,可选
    instance-id: ${spring.application.name}:${spring.cloud.client.ip-address}:${server.port}

5.添加一个订单获取服务

@RestController
public class OrderService {
    @RequestMapping("getOrder")
    public String getOrder(){
        return "{code:0,data:{}}";
    }
}

6.我们启动下这个项目,看看是否正常启动http://localhost:8081/getOrder

我们重新打开http://localhost:8761/,会看到生产者已经注册到注册中心里面了

服务消费者开发

,和生产者一样,只需要将项目名改为eureka-client-consumer

1.修改yml文件

spring:
  application:
    name: eureka-client-order-consumer-service
server:
  port: 8082
eureka:
  client:
    serviceUrl:
      defaultZone: http://yangle:123@localhost:8761/eureka
  instance:
    preferIpAddress: true
    instance-id: ${spring.application.name}:${spring.cloud.client.ip-address}:${server.port}

2.将restTemplate注入到容器中,SpringRestTemplate是Spring 提供的用于访问 Rest 服务的客端, RestTemplate提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率,所以很多客户端比如Android或者第三方服务商都是使用RestTemplate 请求 restful服务

@SpringBootApplication
public class EurekaClientConsumerApplication {

    public static void main(String[] args) {
        SpringApplication.run(EurekaClientConsumerApplication.class, args);
    }

    @Bean(name = "restTemplate")
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }
}

3.添加一个接口去调用生产者提供的服务

@RestController
public class OrderConsumerService {
    @Autowired
    @Qualifier("restTemplate")
    private RestTemplate restTemplate;
    @RequestMapping("getOrder")
    public String getOrder(){
//IP替换为自己的本地IP
        return restTemplate.getForObject("http://IP:8081/getOrder",String.class);
    }
}

这里使用的就是resttemplate去调用这个服务,这种调用方式虽然简单,但是有一个弊端就是当我们这个服务进行集群部署的时候,这一块就很难快进行负载均衡了,因为这里指定了调用哪个节点的服务,当然这一块springcloud也为我们想到了

4.使用注解@LoadBalanced实现通过服务名去调用,修改配置内容

@SpringBootApplication
public class EurekaClientConsumerApplication {

    public static void main(String[] args) {
        SpringApplication.run(EurekaClientConsumerApplication.class, args);
    }

    @Bean(name = "restTemplate")
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }

    @Bean(name = "restTemplate2")
    @LoadBalanced
    public RestTemplate getRestTemplate2() {
        return new RestTemplate();
    }
}

5.添加实现了loadbalence功能的resttemplate

@RestController
public class OrderConsumerService {
    @Autowired
    @Qualifier("restTemplate")
    private RestTemplate restTemplate;
    @Autowired
    @Qualifier("restTemplate2")
    private RestTemplate restTemplate2;
    @RequestMapping("getOrder")
    public String getOrder(){
        return restTemplate.getForObject("http://192.168.31.168:8081/getOrder",String.class);
    }
//    实现负载均衡的服务,不需要指定节点,只需要指定使用的服务名称
    @RequestMapping("getOrderForLoadBalence")
    public String getOrderForLoadBalence(){
        return restTemplate2.getForObject("http://eureka-client-order-service/getOrder",String.class);
    }
}

6.启动项目后,再次访问新接口,看看是否访问成功

7.查看eureka面看。看到消费者也注册进来了

实现高可用的eureka

实现原理:通过添加一个新的注册中心,然后让他们相互注册,实现高可用

复制eureka-server项目,更名为eureka-server-slave

修改eureka-server-slave的配置文件

spring:
  application:
    name: eureka-server
  security:
    user:
      name: yangle
      password: 123
server:
  port: 8762
eureka:
  client:
    serviceUrl:
      defaultZone: http://yangle:123@localhost:8761/eureka

修改eureka-server的配置文件

spring:
  application:
    name: eureka-server
  security:
    user:
      name: yangle
      password: 123
server:
  port: 8761
eureka:
  client:
    serviceUrl:
      defaultZone: http://yangle:123@localhost:8762/eureka

修改producter和consumer的配置文件

生产者
spring:
  application:
    name: eureka-client-order-service
server:
  port: 8081
eureka:
  client:
    serviceUrl:
      defaultZone: http://yangle:123@localhost:8761/eureka,http://yangle:123@localhost:8762/eureka
  instance:
    preferIpAddress: true
    instance-id: ${spring.application.name}:${spring.cloud.client.ip-address}:${server.port}
消费者
spring:
  application:
    name: eureka-client-order-consumer-service
server:
  port: 8082
eureka:
  client:
    serviceUrl:
      defaultZone: http://yangle:123@localhost:8761/eureka,http://yangle:123@localhost:8762/eureka
  instance:
    preferIpAddress: true
    instance-id: ${spring.application.name}:${spring.cloud.client.ip-address}:${server.port}

添加新的注册中心地址,同时向两个注册中心注册服务

重新启动,验证功能

!!!实战功能到此结束,接下来给自己加点理论知识

zookeeper与eureka的区别

因为在分布式领域中有个著名的CAP理论,三者不可能同时存在,要么AP,要么CP,CAP分别代表什么呢

C:一致性

A:可用性

P:分区容错性

现在来说说为什么CAP不能同时共存呢,因为要保证数据的一致性的话,肯定需要在数据同步到其他节点的时候,将数据锁住,停止产生新的数据,这时候将会拒绝新的请求或者让使用者一直处于阻塞等待的状态,只有在同步完成之后才会释放,接收或处理新的请求,这就会造成服务的不可用性,同样的如果保证服务的可用性,那就在数据同步的时候不能进行锁操作,这与数据一致性的必要条件冲突,这也就是CA不能互溶的元婴,有人会说那P呢,P是必须存在的,因为如果是集群那么P就必须存在。

再来说下zookeeper与eureka区别,zookeeper是基于CP上的,舍弃了A,他经常与DUBBO结合,EUREKA强调AP。舍弃了一致性

内容引自:https://blog.csdn.net/alan_gaohaodong/article/details/82899413

Zookeeper保证CP原则:
         1.1当向注册中心查询服务列表时,我们可以容忍注册中心返回的是几分钟以前的注册信息,
  但不能接受服务直接down掉不可用。也就是说,服务注册功能对可用性的要求高于一致性。
  但是zk会出现这一种情况,当master节点因为网络故障与其他节点失去联系时,剩余注册
  功能就会重新进行leader选举看。问题在于,选举leader的时间太长,30~120s,且选举期间
  整个zk集群都是不可用的,这就导致在选举期间注册服务瘫痪。在云部署的环境下,因网络问题
  使得zk集群失去master节点是较大概率会发生的事,虽然服务能够最终恢复,但是漫长的
  选举时间导致的注册长期不可用是不能容忍的。
        1.2Eureka看明白了这一点,因此在设计时就优先保证可用性。Eureka各个节点都是平等
  的,几个节点挂掉不会影响正常节点的工作,剩余节点依然可以提供注册和查询服务。
  而Eureka的客户端在向某个Eureka注册或者如果发现链接失败时,则会自动切换至其他节点,
  只要有一台Eureka还在,就能保证注册服务可用(保证可用),只不过查到的信息可能不是
  最新的(不保证一致性)。除此以外,Eureka还有一种自我保护机制,如果在15分钟内超过85%
  的节点都没有正常的心跳,那么Eureka就认为客户端与注册中心出现了网络故障,此时会出现
  一下几种情况:
      (1)Eureka不在从注册列表中移除因为长时间没收到心跳而应该过期的服务
      (2)Eureka仍然能够接受新服务的注册和查询请求,但是不会被同步到其他节点上
               (保证当前节点依然可用)
      (3)当网络稳定时,当前实例新的注册信息会被同步到其他节点中
  因此,Eureka可以很好的应对因网络故障导致部分节点失去联系的情况,而不会像zk那样
     是整个注册服务瘫痪。

有关eureka面试题及解答

1.介绍下CAP

答案如上

2.EUREKA与zookeeper区别

答案如上

总结

通过本章介绍,了解了什么是注册中心,已经能够提供注册中心功能的框架,紧接着介绍了eureka的入门使用及如何保证eureka注册中心的高可用,最后讨论了zookeeper与eureka的区别和面试中常见的有关eureka的问题,后面继续讲解springcloud的相关知识,下一节会介绍如何实现客户端的负载均衡。

欢迎大家关注我的公众号,回复eureka,获取本章源码,回复“资料领取”,获取人工智能、大数据等更多学习视频资料,如有侵权,请联系作者立即删除!

                                       

  乐哉码农

                                                         

猜你喜欢

转载自blog.csdn.net/weixin_34311210/article/details/104089608