源无极

导航

 

1、什么是微服务的注册中心


简介:讲解什么是注册中心,常用的注册中心有哪些 (画图)

理解注册中心服务管理,核心是有个服务注册表,心跳机制动态维护(保证每一个服务可以用

服务提供者provider: 启动的时候向注册中心上报自己的网络信息

服务消费者consumer: 启动的时候向注册中心上报自己的网络信息,拉取provider的相关网络信息

 


为什么要用:
微服务应用和机器越来越多,调用方需要知道接口的网络地址,如果靠配置文件的方式去控制网络地址,对于动态新增机器,维护带来很大问题

主流的注册中心:
zookeeper、Eureka、consul、etcd 等

 

2、分布式应用知识CAP理论知识


简介:讲解分布式核心知识CAP理论

CAP定理:
指的是在一个分布式系统中,Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可同时获得。

 

一致性(C):在分布式系统中的所有数据备份,在同一时刻是否同样的值。(所有节点在同一时间的数据完全一致,越多节点,数据同步越耗时)

 


可用性(A):负载过大后,集群整体是否还能响应客户端的读写请求。(服务一直可用,而且是正常响应时间

 


分区容错性(P):分区容忍性,就是高可用性,一个节点崩了,并不影响其它的节点(100个节点,挂了几个,不影响服务,越多机器越好

 


CAP理论就是说在分布式存储系统中,最多只能实现上面的两点。而由于当前的网络硬件肯定会出现延迟丢包等问题,所以分区容忍性是我们必须需要实现的所以我们只能在一致性和可用性之间进行权衡

 优秀博客分享:

CAP理论与MongoDB一致性、可用性的一些思考

 

3、分布式系统CAP原理常见面试题和注册中心选择(面试)


简介:讲解CAP原则在面试中回答和注册中心选择

1)C A 满足的情况下,P不能满足的原因:
数据同步(C)需要时间,也要正常的时间内响应(A),那么机器数量就要少,所以P就不满足

2)CP 满足的情况下,A不能满足的原因:
数据同步(C)需要时间, 机器数量也多(P),但是同步数据需要时间,所以不能再正常时间内响应,所以A就不满足

3)AP 满足的情况下,C不能满足的原因:
机器数量也多(P),正常的时间内响应(A),那么数据就不能及时同步到其他节点,所以C不满足

 

 

注册中心选择:
Zookeeper:CP设计,保证了一致性,集群搭建的时候,某个节点失效,则会进行选举行的leader,或者半数以上节点不可用,则无法提供服务,因此可用性没法满足

Eureka:AP原则,无主从节点,一个节点挂了,自动切换其他节点可以使用,去中心化

 

结论:分布式系统中P,肯定要满足,所以只能在CA中二选一
没有最好的选择,最好的选择是根据业务场景来进行架构设计

如果要求一致性,则选择zookeeper,如金融行业

如果要去可用性,则Eureka,如电商系统

 

4、SpringCloud微服务核心组件Eureka介绍和闭源后影响
简介:
SpringCloud体系介绍
官方地址:http://projects.spring.io/spring-cloud/


Eureka的基础知识-->画图讲解交互流程,服务提供者<-->服务消费者 ;

 

Eureka 2.x闭源后选择

参考:https://www.jianshu.com/p/d32ae141f680
https://blog.csdn.net/zjcjava/article/details/78608892

 

Eureka简介:
     Eureka是Netflix开发的服务发现框架,本身是一个基于REST的服务,主要用于定位运行在AWS域中的中间层服务,
达到负载均衡和中间层服务故障转移的目的Spring Cloud将它集成在其子项目spring-cloud-netflix中,以实现Spring Cloud的服务发现功能。
Eureka 项目相当活跃,代码更新相当频繁,目前最新的版本是1.5.5。Eureka 2.0的版本也正在紧锣密鼓地开发中,
2.0将会带来更好的扩展性,并且使用细粒度的订阅模型取代了基于拉取的模型,但是由于还没有Release,故而不作讲解。

      上图是来自Eureka官方的架构图,大致描述了Eureka集群的工作过程由于图比较复杂,可能比较难看懂,这边用通俗易懂的语言翻译一下:
- Application Service 就相当于本书中的服务提供者(用户微服务),Application Client就相当于本书中的服务消费者(电影微服务)
- Make Remote Call,可以简单理解为调用RESTful的接口;
- us-east-1c、us-east-1d等是zone,它们都属于us-east-1这个region;
       由图可知Eureka包含两个组件:Eureka Server 和 Eureka Client。
Eureka Server提供服务注册服务,各个节点启动后,会在Eureka Server中进行注册,这样Eureka Server中的服务注册表中将会存储所有可用服务节点的信息,
服务节点的信息可以在界面中直观的看到。
Eureka Client是一个Java客户端,用于简化与Eureka Server的交互,客户端同时也具备一个内置的、使用轮询(round-robin)负载算法的负载均衡器。
在应用启动后,将会向Eureka Server发送心跳(默认周期为30秒)。果Eureka Server在多个心跳周期内没有接收到某个节点的心跳
Eureka Server将会从服务注册表中把这个服务节点移除(默认90秒)
Eureka Server之间将会通过复制的方式完成数据的同步。(详见Eureka高可用章节)
Eureka提供了客户端缓存的机制,即使所有的Eureka Server都挂掉,客户端依然可以利用缓存中的信息消费其他服务的API。
 
综上,Eureka通过心跳检测、健康检查、客户端缓存等机制,确保了系统的高可用性、灵活性和可伸缩性。
 
服务注册表
是一个记录当前可用服务实例的网络信息的数据库,是服务发现机制的核心。服务注册表提供查询API和管理API
,使用查询API获得可用的服务实例,使用管理API实现注册和注销;
 
服务注册
很好理解,就是服务启动时,将服务的网络地址注册到服务注册表中;
健康检查
服务发现组件会通过一些机制定时检测已注册的服务,如果发现某服务无法访问了(可能是某几个心跳周期后),就将该服务从服务注册表中移除。

 

5、服务注册和发现Eureka Server搭建实战


简介:使用IDEA搭建Eureka服务中心Server端并启动,项目基本骨架介绍

官方文档:http://cloud.spring.io/spring-cloud-netflix/single/spring-cloud-netflix.html#spring-cloud-eureka-server

第一步:创建项目

 1)IDEA开发

2)

3)2.0.7的版本

4)

最后点击完成选择新窗口建立工程,注意新建工程的时候下载jar包慢的话自己修改maven地址

maven地址: https://www.cnblogs.com/sword-successful/p/6408281.html

pom(版本2.0.7有问题的话可以改为2.0.3)

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 3     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 4     <modelVersion>4.0.0</modelVersion>
 5     <parent>
 6         <groupId>org.springframework.boot</groupId>
 7         <artifactId>spring-boot-starter-parent</artifactId>
 8         <version>2.0.3.RELEASE</version>
 9         <relativePath/> <!-- lookup parent from repository -->
10     </parent>
11     <groupId>com.po</groupId>
12     <artifactId>eureka_server</artifactId>
13     <version>0.0.1-SNAPSHOT</version>
14     <name>eureka_server</name>
15     <description>Demo project for Spring Boot</description>
16 
17     <!--<properties>
18         <java.version>1.8</java.version>
19         <spring-cloud.version>Finchley.SR2</spring-cloud.version>
20     </properties>-->
21     <properties>
22         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
23         <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
24         <java.version>1.8</java.version>
25         <spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
26     </properties>
27 
28     <dependencies>
29         <dependency>
30             <groupId>org.springframework.cloud</groupId>
31             <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
32         </dependency>
33 
34         <dependency>
35             <groupId>org.springframework.boot</groupId>
36             <artifactId>spring-boot-starter-test</artifactId>
37             <scope>test</scope>
38         </dependency>
39     </dependencies>
40 
41     <dependencyManagement>
42         <dependencies>
43             <dependency>
44                 <groupId>org.springframework.cloud</groupId>
45                 <artifactId>spring-cloud-dependencies</artifactId>
46                 <version>${spring-cloud.version}</version>
47                 <type>pom</type>
48                 <scope>import</scope>
49             </dependency>
50         </dependencies>
51     </dependencyManagement>
52 
53     <build>
54         <plugins>
55             <plugin>
56                 <groupId>org.springframework.boot</groupId>
57                 <artifactId>spring-boot-maven-plugin</artifactId>
58             </plugin>
59         </plugins>
60     </build>
61 
62 </project>

 


第二步: 添加注解 @EnableEurekaServer

 1 package com.po.eureka_server;
 2 
 3 import org.springframework.boot.SpringApplication;
 4 import org.springframework.boot.autoconfigure.SpringBootApplication;
 5 import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
 6 
 7 @SpringBootApplication
 8 @EnableEurekaServer
 9 public class EurekaServerApplication {
10 
11     public static void main(String[] args) {
12         SpringApplication.run(EurekaServerApplication.class, args);
13     }
14 
15 }

 


第三步:增加配置application.yml

 1 server:
 2   port: 8081
 3 eureka:
 4   instance:
 5     hostname: localhost
 6   client:
 7   #声明自己是一个服务器,不加的话会报错
 8     registerWithEureka: false
 9     fetchRegistry: false
10     serviceUrl:
11           defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

 不配置报错

com.sun.jersey.api.client.ClientHandlerException: java.net.ConnectException: Connection refused: connect

第四步:访问注册中心页面

 

 注意:配置文件有严格的空格缩进

 

 

6、服务注册和发现之Eureka Client搭建商品服务实战
简介:搭建用商品服务,并将服务注册到注册中心

1、创建一个SpirngBoot应用,增加服务注册和发现依赖

1)同理创建product_service

2)

 

 pom

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 3     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 4     <modelVersion>4.0.0</modelVersion>
 5     <parent>
 6         <groupId>org.springframework.boot</groupId>
 7         <artifactId>spring-boot-starter-parent</artifactId>
 8         <version>2.0.3.RELEASE</version>
 9         <relativePath/> <!-- lookup parent from repository -->
10     </parent>
11     <groupId>com.po</groupId>
12     <artifactId>product_service</artifactId>
13     <version>0.0.1-SNAPSHOT</version>
14     <name>product_service</name>
15     <packaging>jar</packaging>
16     <description>Demo project for Spring Boot</description>
17 
18     <properties>
19         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
20         <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
21         <java.version>1.8</java.version>
22         <spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
23     </properties>
24 
25     <dependencies>
26         <dependency>
27             <groupId>org.springframework.boot</groupId>
28             <artifactId>spring-boot-starter-web</artifactId>
29         </dependency>
30         <dependency>
31             <groupId>org.springframework.cloud</groupId>
32             <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
33         </dependency>
34 
35         <dependency>
36             <groupId>org.springframework.boot</groupId>
37             <artifactId>spring-boot-starter-test</artifactId>
38             <scope>test</scope>
39         </dependency>
40     </dependencies>
41 
42     <dependencyManagement>
43         <dependencies>
44             <dependency>
45                 <groupId>org.springframework.cloud</groupId>
46                 <artifactId>spring-cloud-dependencies</artifactId>
47                 <version>${spring-cloud.version}</version>
48                 <type>pom</type>
49                 <scope>import</scope>
50             </dependency>
51         </dependencies>
52     </dependencyManagement>
53 
54     <build>
55         <plugins>
56             <plugin>
57                 <groupId>org.springframework.boot</groupId>
58                 <artifactId>spring-boot-maven-plugin</artifactId>
59             </plugin>
60         </plugins>
61     </build>
62 
63 
64 
65 </project>

 

 

2、开发商品列表接口,商品详情接口

1)service接口

 1 package com.po.product_service.service;
 2 
 3 import com.po.product_service.domain.Product;
 4 
 5 import java.util.List;
 6 
 7 public interface ProductService {
 8     List<Product> listProduct();//产品列表
 9     Product findProduct(int id);//查询单个商品
10 
11 }

 

2)service接口实现类

 

 1 package com.po.product_service.service.impl;
 2 
 3 import com.po.product_service.domain.Product;
 4 import com.po.product_service.service.ProductService;
 5 import org.springframework.stereotype.Service;
 6 
 7 import java.util.*;
 8 
 9 @Service
10 public class ProductServiceImpl implements ProductService {
11      //此处不访问数据库了,模拟数据即可
12     private  static  final Map<Integer,Product> map =new HashMap<Integer,Product>();
13   static {
14       Product p1 = new Product(1, "iPhone8", 8999, 10);
15       Product p2 = new Product(2, "iPhone7", 7999, 20);
16       Product p3 = new Product(3, "iPhone6", 6999, 30);
17       Product p4 = new Product(4, "iPhone4", 5999, 50);
18       Product p5 = new Product(5, "iPhone5", 999, 10);
19       Product p6 = new Product(6, "iPhoneX", 9999, 60);
20       map.put(p1.getId(),p1);
21       map.put(p2.getId(),p2);
22       map.put(p3.getId(),p3);
23       map.put(p4.getId(),p4);
24       map.put(p5.getId(),p5);
25       map.put(p6.getId(),p6);
26   }
/*
查询所有商品
*/
27 @Override 28 public List<Product> listProduct() { 29 Collection<Product> po = map.values(); 30 List<Product> list = new ArrayList<>(po); 31 return list; 32 } 33 34 @Override 35 public Product findProduct(int id) { 36 return map.get(id); 37 } 38 }

 

3)controller

 1 package com.po.product_service.controller;
 2 
 3 import com.po.product_service.domain.Product;
 4 import com.po.product_service.service.ProductService;
 5 import org.springframework.beans.factory.annotation.Autowired;
 6 import org.springframework.web.bind.annotation.RequestMapping;
 7 import org.springframework.web.bind.annotation.RequestParam;
 8 import org.springframework.web.bind.annotation.RestController;
 9 
10 import java.util.List;
11 
12 @RestController
13 @RequestMapping("/api/vi/product")
14 public class ProductController {
15     @Autowired
16     private ProductService productService;
17     /*
18       获取所有商品列表
19      */
20     @RequestMapping("list")
21     public List<Product> findProduct(){
22     return  productService.listProduct();
23     }
24     /*
25     通过id查出商品
26    */
27     @RequestMapping("findById")
28     public Product findById(@RequestParam("id") int id){
29         return productService.findProduct(id);
30     }
31 
32 }

 

4)domain

 1 package com.po.product_service.domain;
 2 
 3 import java.io.Serializable;
 4 
 5 public class Product implements Serializable {
 6 private int id;
 7 private  String name;
 8 //价格
 9 private  int price;
10 //库存
11 private int store;
12 
13     public Product(int id, String name, int price, int store) {
14         this.id = id;
15         this.name = name;
16         this.price = price;
17         this.store = store;
18     }
19 
20     public Product() {
21     }
22 
23     public int getId() {
24         return id;
25     }
26 
27     public void setId(int id) {
28         this.id = id;
29     }
30 
31     public String getName() {
32         return name;
33     }
34 
35     public void setName(String name) {
36         this.name = name;
37     }
38 
39     public int getPrice() {
40         return price;
41     }
42 
43     public void setPrice(int price) {
44         this.price = price;
45     }
46 
47     public int getStore() {
48         return store;
49     }
50 
51     public void setStore(int store) {
52         this.store = store;
53     }
54 }

 


3、配置文件加入注册中心地址
使用eureka客户端 官方文档:http://cloud.spring.io/spring-cloud-netflix/single/spring-cloud-netflix.html#netflix-eureka-client-starter

 

 1 #本服务的端口
 2 server:
 3   port: 8771
 4 #defaultZone地址指向的是注册中心
 5 eureka:
 6   client:
 7     serviceUrl:
 8       defaultZone: http://localhost:8761/eureka/
 9 #服务的名称
10 spring:
11   application:
12     name: product_service

 

 

注意:将我们的注册中心端口号改为8761,

启动eureka_serviceh和product_service

1)访问数据

2)查看注册中心

如何再添加一个服务?

2)

3)启动

注册中心

 

 此时8772端口也是可以访问的

 

扩展:

启动访问注册中心(实际开发中做集群的时候出现的如下情况)

 

7、Eureka服务注册中心配置控制台问题处理
简介:讲解服务注册中心管理后台,(后续还会细讲)

问题:eureka管理后台出现一串红色字体:是警告,说明有服务上线率低

EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY'RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE.

关闭检查方法:eureka服务端配置文件加入
server:
enable-self-preservation: false
注意:自我保护模式禁止关闭,默认是开启状态true


问题二:为什么只加一个注册中心地址,就可以注册(官方文档的解释)
       By having spring-cloud-starter-netflix-eureka-client on the classpath, your application automatically registers with the Eureka Server. Configuration is required to locate the Eureka server, as shown in the following example:

通过在类路径上安装spring-cloud-starter-netflix-eureka-client,您的应用程序会自动向Eureka Server注册。 找到Eureka服务器需要进行配置,如以下示例所示:

posted on 2018-12-18 22:09  源无极  阅读(148)  评论(0编辑  收藏  举报