SpringCloud技术点介绍以及设计模式和SpringCloud netfix解决方案

SpringCloud

在众多的架构中,spring家族占据了主导的位置,同样对于spring衍生出的产品我们也应该去探索,今天我们将看下什么是微服务架构,以及微服务架构的解决方案,

学习微服务架构必须有三年以上的开发的经验:

微服务概念

把一个大型的单体应用拆分为数十个支持微服务,他可扩展单个组件而不是整个的应用程序堆栈,从而满足服务等级协议

定义:围绕业务领域组件进行创建组件,这些应用可独立进行开发,管理迭代,在分散的组件中使用云架构和平台式部署,管理,和服务功能,使得产品交互更加的简单

本质:是用一些功能比较明确的,业务精练的服务去解决更大的更实际的问题,(2012年为微服务元年)

微服务架构:

微服务架构是一种架构概念,旨在通过将功能分解到各个离散的服务中以实现对解决方案的解耦。 它的主要作用是将功能分解到离散的各个服务当中,从而降低系统的耦合性,并提供更加灵活的服务支持。

缺点

​ 1.微服务的另一个挑战是分区数据库架构。更新多个业务实体的业务事务是相当普遍的。这些事务在单体应用中的实现显得微不足道,因为单体只存在一个单独的数据库。在基于微服务的应用程序中,您需要更新不同服务所用的数据库。

​ 通常不会选择分布式事务,不仅仅是因为 CAP 定理。他们根本不支持如今高度可扩展的 NoSQL 数据库和消息代理。

​ 2.部署复杂

​ 3.测试微服务应用程序也很复杂

​ 4.微服务架构模式的另一个主要挑战是实现了跨越多服务变更

​ 5.每个服务都有多个运行时实例。还有更多的移动部件需要配置、部署、扩展和监控

​ 构建复杂的微服务应用程序本质上是困难的。单体架构模式只适用于简单、轻量级的应用程序,如果您使用它来构建复杂应用,您最终会陷入痛苦的境地。

​ 微服务架构模式是复杂、持续发展应用的一个更好的选择。尽管它存在着缺点和实现挑战

​ 微服务的数据的库的设置:是反范式的设计模式:根据情况来设计不同的数据库

优点
  • 1.第一,它解决了复杂问题。它把可能会变得庞大的单体应用程序分解成一套服务。虽然功能数量不变,但是应用程序已经被分解成可管理的块或者服务。

  • 2.这种架构使得每个服务都可以由一个团队独立专注开发。开发者可以自由选择任何符合服务 API 契约的技术。

  • 3.微服务架构模式可以实现每个微服务独立部署。开发人员根本不需要去协调部署本地变更到服务。这些变更一经测试即可立即部署

  • 4.微服务架构模式使得每个服务能够独立扩展。您可以仅部署满足每个服务的容量和可用性约束的实例数目。此外,您可以使用与服务资源要求最匹配的硬件。目标在于充分分解应用程序以方便应用的敏捷开发和部署,

CAP定理:

​ 一个分布式系统最多只能同时满足一致性(Consistency)、可用性(Availability)和分区容错性(Partition tolerance)这三项中的两项。

​ C:即更新操作成功并返回客户端完成后,所有节点在同一时间的数据完全一致。

​ A:即服务一直可用,而且是正常响应时间

​ P:即分布式系统在遇到某节点或网络分区故障的时候,仍然能够对外提供满足一致性和可用性的服务

CAP权衡:

​ C 必须保证。网络发生故障宁可停止服务,这是保证 CA,舍弃 P。貌似这几年国内银行业发生了不下 10 起事故,但影响面不大,报到也不多,广大群众知道的少。

​ 还有一种是保证 CP,舍弃 A。例如网络故障是只读不写。孰优孰略,没有定论,只能根据场景定夺,适合的才是最好的

BASE理论:

​ ebay架构师在 ACM 上发表文章提出 BASE 理论,BASE 理论是对 CAP 理论的延伸,核心思想是即使无法做到强一致性(Strong Consistency,CAP 的一致性就是强一致性),但应用可以采用适合的方式达到最终一致性(Eventual Consitency)。

服务间的通信

同步调用:网络间只有字符串可以通过穿透防火墙

​ Rest:(对外)Http通信

​ Rest API

​ String json=/usr/list;
​ User usr=new User();
​ usr.setId(json.getId)

​ 使用框架:springboot+Spring Cloud;

​ RPC:(对内) 远程过程调用

​ 调用也是对内部的,同样需要new出的,但是不是直接new User()的,而是new 的另一个框架:Dubbo

​ 问题:就会出现阻塞,出现单点故障,

​ RPC 也有自己的优点,传输协议更高效,安全更可控,

​ 特别在一个公司内部,如果有统一个的开发规范和统一的服务框架时,

​ 他的开发效率优势更明显些。就看各自的技术积累实际条件,自己的选择了

异步消息调用:

​ 异步消息的方式在分布式系统中有特别广泛的应用,他既能减低调用服务之间的耦合,又能成为调用之间的缓冲,确保消息积压不会冲垮被调用方, 同时能保证调用方的服务体验,继续干自己该干的活,不至于被后台性能拖慢。不过需要付出的代价是一致性的减弱,需要接受数据 最终一致性;
还有就是后台服务一般要实现 幂等性,因为消息送出于性能的考虑一般会有重复(保证消息的被收到且仅收到一次对性能是很大的考验);最后就是必须引入一个独立的 Broker

​ Kafka

​ Notify

​ MessageQueue ​

服务间是如何发现的呢:

​ 在微服务架构中,一般每一个服务都是有多个拷贝,来做负载均衡。一个服务随时可能下线,也可能应对临时访问压力增加新的服务节点。

​ 服务之间如何相互感知?服务如何管理?

​ 这就是服务发现的问题了。一般有两类做法,也各有优缺点。基本都是通过 Zookeeper 等类似技术做服务注册信息的分布式管理。

​ 当服务上线时,服务提供者将自己的服务信息注册到 ZK(或类似框架),并通过心跳维持长链接,实时更新链接信息。服务调用者通过 ZK 寻址,根据可定制算法,找到一个服务,还可以将服务信息缓存在本地以提高性能。当服务下线时,ZK 会发通知给服务客户端

基于客户端的服务注册与发现

​ 优点是架构简单,扩展灵活,只对服务注册器依赖。缺点是客户端要维护所有调用服务的地址,有技术难度,一般大公司都有成熟的内部框架支持,比如 Dubbo。

​ 每次需要调用服务时需要在zookeeper中注册发现中查询,前提是每一个服务新建时需要在这个注册中心,进行ip注册和端口,服务名称。

基于服务端的服务注册与发现:

​ 优点是简单,所有服务对于前台调用方透明,一般在小公司在云服务上部署的应用采用的比较多。

​ 主要有这几个框架:
​ Eureka:
​ Consul:
​ Zookeeper:

​ 如果服务挂了如何解决呢:

​ 重试机制:即当没响应时他会自己再次发送请求,

​ 限流:秒杀机制,直接在客户端中让百分之90的人不能直接访问到服务,而是直接提示出,

​ 熔断机制:在服务端进行流量的控制

​ 负载均衡: 降级(本地缓存)

服务注册与发现原理:

dO4A81.png

单点故障:

​ 在分不式锁服务中,有一种典型的应用场景,通过集群对Master进行选举,
​ 即主节点不能使用的话,既不能为从节点提供服务。
​ 传统的解决方案:主节点-------》备用主节点
​ 备用主节点------》》从节点 《《--------主节点
​ 这种方式网络突然有问题时会进行对回复时就会丢失包,而这样的情况就是就会把两个主节点都是在这里
​ 主要使用zookeeper来解决这个问题,服务注册与发现
​ 引入:为什么使用分布式锁:

微服务架构的设计模式:

微服务架构需要考虑的问题:
  • API Gateway
  • 服务间调用
  • 服务发现
  • 服务容错
  • 服务部署
  • 数据调用

在这里插入图片描述

微服务设计模式:
  • ​ 聚合器微服务形式::由api网关进行对其聚合

在这里插入图片描述

  • ​ 代理微服务设计模式:代理委派请求,在这种情况下,客户端并不聚合数据,但会根据业务需求的差别调用不同的微服务。代理可以仅仅委派请求,也可以进行数据转换工作

在这里插入图片描述

  • ​ 链式微服务设计模式:链式同步调用,这种模式在接收到请求后会产生一个经过合并的响应

在这里插入图片描述

  • ​ 分支微服务设计模式:同时允许两个微服务链,这种模式是聚合器模式的扩展,允许同时调用两个微服务链

在这里插入图片描述

  • ​ 数据共享微服务设计模式:SQL数据库反规范化可能会导致数据重复和不一致。自治是微服务的设计原则之一,就是说微服务是全栈式服务。但在重构现有的“单体应用(Monolithic Application)”时,SQL 数据库反规范化可能会导致数据重复和不一致。因此,在单体应用到微服务架构的过渡阶段,可以使用这种设计模式

在这里插入图片描述

  • ​ 异步消息传递微服务设计模式:使用消息队列,虽然 REST 设计模式非常流行,但它是同步的,会造成阻塞。因此部分基于微服务的架构可能会选择使用消息队列代替 REST 请求/响应
    在这里插入图片描述
微服务架构开发建议:
  	应用程序的核心是业务逻辑,按照业务或客户需求组织资源(这是最难的)
   做有生命的产品,而不是项目
  	全栈化
  	后台服务贯彻 Single Responsibility Principle(单一职责原则)
  	VM -> Docker
  	DevOps

  	springCloud 基于springboot的技术技术框架;
  	java原生云开发=springCloud+spring boot

分布式系统开发一定会遇到的四个问题以及解决方案:

​ 1.服务众多,客户端如何访问。

​ 2.服务众多,服务之间如何通信。

​ 3.服务众多,如何治理。

​ 4.服务众多,如果挂了怎么办;

这四个问题对应了解决四个问题的方式:

​ 1.API网关,服务路由

​ 2.Http,RPC,异步调用

​ 3.服务注册与发现 -》高可用

​ 4.熔断,限流,服务降级

解决方案:

​ SpringCloud,spring Cloud是一套生态,是为了解决微服务架构遇到的问题,想要使用Spring Cloud必须基于Spring Boot

1.Spring Cloud Netflix

​ API网关,zuul组件

​ 服务注册与发现,Eureka

​ Fegin -> http Client -->http通信方式,同步阻塞

熔断机制 Hystrix

2.Apache Dubbo Zookeeper

Dubbo是一个高效性能的 Java RPC 通信框架,2.6.x

服务注册与发现,Zookeeper,

API网关 没有  找第三方或自己实现。

服务挂了,Hystrix

3.Spring Cloud Alibaba

Spring Cloud Alibaba致力于提供微服务开发的一站式解决方案。此项目包含开发分布式应用微服务的必需组件,方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。

依托 Spring Cloud Alibaba,您只需要添加一些注解和少量配置,就可以将 Spring Cloud 应用接入阿里微服务解决方案,通过阿里中间件来迅速搭建分布式应用系统。

下一代会是什么呢,Service Mesh 服务网格化,Istio 可能是需要掌握的一套微服务解决方案。

SpringCloud Netflix:

到2019目前最流行的微服务架构解决方案是:springBoot+spring cloud Netflix

Spring Cloud 为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智能路由,微代理,控制总线)。分布式系统的协调导致了样板模式, 使用 Spring Cloud 开发人员可以快速地支持实现这些模式的服务和应用程序。他们将在任何分布式环境中运行良好,包括开发人员自己的笔记本电脑,裸机数据中心,以及 Cloud Foundry 等托管平台。

​ Spring Cloud 是基于Spring Boot进行开发,并且都是使用 Maven 做项目管理工具。 然而在2019年Spring Cloud Netflix 开始进入维护模式。所以使用的少了。

下面看看如何使用Spring Cloud Netflix 搭建一个微服务架构

创建一个依赖管理项目:
<?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>

            <parent>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-parent</artifactId>
                <version>2.0.2.RELEASE</version>
            </parent>

            <groupId>com.funtl</groupId>
            <artifactId>hello-spring-cloud-dependencies</artifactId>
            <version>1.0.0-SNAPSHOT</version>
            <packaging>pom</packaging>

            <name>hello-spring-cloud-dependencies</name>
            <url>http://www.funtl.com</url>
            <inceptionYear>2018-Now</inceptionYear>

            <properties>
                <!-- Environment Settings -->
                <java.version>1.8</java.version>
                <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
                <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

                <!-- Spring Settings -->
                <spring-cloud.version>Finchley.RC1</spring-cloud.version>
            </properties>

            <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>

            <build>
                <plugins>
                    <!-- Compiler 插件, 设定 JDK 版本 -->
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-compiler-plugin</artifactId>
                        <configuration>
                            <showWarnings>true</showWarnings>
                        </configuration>
                    </plugin>

                    <!-- 打包 jar 文件时,配置 manifest 文件,加入 lib 包的 jar 依赖 -->
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-jar-plugin</artifactId>
                        <configuration>
                            <archive>
                                <addMavenDescriptor>false</addMavenDescriptor>
                            </archive>
                        </configuration>
                        <executions>
                            <execution>
                                <configuration>
                                    <archive>
                                        <manifest>
                                            <!-- Add directory entries -->
                                            <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
                                            <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
                                            <addClasspath>true</addClasspath>
                                        </manifest>
                                    </archive>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>

                    <!-- resource -->
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-resources-plugin</artifactId>
                    </plugin>

                    <!-- install -->
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-install-plugin</artifactId>
                    </plugin>

                    <!-- clean -->
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-clean-plugin</artifactId>
                    </plugin>

                    <!-- ant -->
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-antrun-plugin</artifactId>
                    </plugin>

                    <!-- dependency -->
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-dependency-plugin</artifactId>
                    </plugin>
                </plugins>

                <pluginManagement>
                    <plugins>
                        <!-- Java Document Generate -->
                        <plugin>
                            <groupId>org.apache.maven.plugins</groupId>
                            <artifactId>maven-javadoc-plugin</artifactId>
                            <executions>
                                <execution>
                                    <phase>prepare-package</phase>
                                    <goals>
                                        <goal>jar</goal>
                                    </goals>
                                </execution>
                            </executions>
                        </plugin>

                        <!-- YUI Compressor (CSS/JS压缩) -->
                        <plugin>
                            <groupId>net.alchim31.maven</groupId>
                            <artifactId>yuicompressor-maven-plugin</artifactId>
                            <version>1.5.1</version>
                            <executions>
                                <execution>
                                    <phase>prepare-package</phase>
                                    <goals>
                                        <goal>compress</goal>
                                    </goals>
                                </execution>
                            </executions>
                            <configuration>
                                <encoding>UTF-8</encoding>
                                <jswarn>false</jswarn>
                                <nosuffix>true</nosuffix>
                                <linebreakpos>30000</linebreakpos>
                                <force>true</force>
                                <includes>
                                    <include>/*.js</include>
                                    <include>/.css</include>
                                </includes>
                                <excludes>
                                    <exclude>**/.min.js</exclude>
                                    <exclude>*/.min.css</exclude>
                                </excludes>
                            </configuration>
                        </plugin>
                    </plugins>
                </pluginManagement>

                <!-- 资源文件配置 -->
                <resources>
                    <resource>
                        <directory>src/main/java</directory>
                        <excludes>
                            <exclude>*/.java</exclude>
                        </excludes>
                    </resource>
                    <resource>
                        <directory>src/main/resources</directory>
                    </resource>
                </resources>
            </build>

            <repositories>
                <repository>
                    <id>aliyun-repos</id>
                    <name>Aliyun Repository</name>
                    <url>http://maven.aliyun.com/nexus/content/groups/public</url>
                    <releases>
                        <enabled>true</enabled>
                    </releases>
                    <snapshots>
                        <enabled>false</enabled>
                    </snapshots>
                </repository>

                <repository>
                    <id>sonatype-repos</id>
                    <name>Sonatype Repository</name>
                    <url>https://oss.sonatype.org/content/groups/public</url>
                    <releases>
                        <enabled>true</enabled>
                    </releases>
                    <snapshots>
                        <enabled>false</enabled>
                    </snapshots>
                </repository>
                <repository>
                    <id>sonatype-repos-s</id>
                    <name>Sonatype Repository</name>
                    <url>https://oss.sonatype.org/content/repositories/snapshots</url>
                    <releases>
                        <enabled>false</enabled>
                    </releases>
                    <snapshots>
                        <enabled>true</enabled>
                    </snapshots>
                </repository>

                <repository>
                    <id>spring-snapshots</id>
                    <name>Spring Snapshots</name>
                    <url>https://repo.spring.io/snapshot</url>
                    <snapshots>
                        <enabled>true</enabled>
                    </snapshots>
                </repository>
                <repository>
                    <id>spring-milestones</id>
                    <name>Spring Milestones</name>
                    <url>https://repo.spring.io/milestone</url>
                    <snapshots>
                        <enabled>false</enabled>
                    </snapshots>
                </repository>
            </repositories>

            <pluginRepositories>
                <pluginRepository>
                    <id>aliyun-repos</id>
                    <name>Aliyun Repository</name>
                    <url>http://maven.aliyun.com/nexus/content/groups/public</url>
                    <releases>
                        <enabled>true</enabled>
                    </releases>
                    <snapshots>
                        <enabled>false</enabled>
                    </snapshots>
                </pluginRepository>
            </pluginRepositories>
        </project>

创建服务注册与发现:
  • 用的是Eureak是一个服务注册和发现模块(与zookeeper的作用是一样的)
  • 引入配置文件pom.xml
  • 启动一个服务注册中心:需要注解@EnableEureakaServcer
  • 配置application.yml文件:每一个实例注册之后需要向注册中心发送心跳(因此可以在内存中完成),在默认情况下 Erureka Server 也是一个 Eureka Client ,必须要指定一个 Server。
  • 通过服务可以打开浏览器进行访问http://localhost:8761
创建服务提供者:

​ 当 Client 向 Server 注册时,它会提供一些元数据,例如主机和端口,URL,主页等。Eureka Server 从每个 Client 实例接收心跳消息。 如果心跳超时,则通常将该实例从注册 Server 中删除

引入pom.xm文件:

application中的yml

spring:
  application:
    name: hello-spring-cloud-service-admin

server:
  port: 8762

eureka:
  client:
     serviceUrl:
        defaultZone: http://localhost:8761/eureka/   

创建服务消费者Ribbon:
 pom.xml:
<?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>

    <parent>
        <groupId>com.funtl</groupId>
        <artifactId>hello-spring-cloud-dependencies</artifactId>
        <version>1.0.0-SNAPSHOT</version>
        <relativePath>../hello-spring-cloud-dependencies/pom.xml</relativePath>
    </parent>

    <artifactId>hello-spring-cloud-web-admin-ribbon</artifactId>
    <packaging>jar</packaging>

    <name>hello-spring-cloud-web-admin-ribbon</name>
    <url>http://www.funtl.com</url>
    <inceptionYear>2018-Now</inceptionYear>

    <dependencies>
        <!-- Spring Boot Begin -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- Spring Boot End -->

        <!-- Spring Cloud Begin -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
        </dependency>
        <!-- Spring Cloud End -->

        <!-- 解决 thymeleaf 模板引擎一定要执行严格的 html5 格式校验问题 -->
        <dependency>
            <groupId>net.sourceforge.nekohtml</groupId>
            <artifactId>nekohtml</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <mainClass>com.funtl.hello.spring.cloud.web.admin.ribbon.WebAdminRibbonApplication</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

在application.yml中书写配置文件:
spring:
  application:
    name: hello-spring-cloud-service-admin

server:
  port: 8762

eureka:
  client:
     serviceUrl:
        defaultZone: http://localhost:8761/eureka/   

​ 创建服务feign:feign是集成了ribbon的一个服务消费者:项目中使用用Feign 可以理解为将ribbon峰会在哪个了一次

熔断器防止服务雪崩:

​ 在微服务架构中,根据业务来拆分成一个个的服务,服务与服务之间可以通过 RPC 相互调用,在 Spring Cloud 中可以用 RestTemplate + Ribbon 和 Feign 来调用。为了保证其高可用,单个服务通常会集群部署。

​ 由于网络原因或者自身的原因,服务并不能保证 100% 可用,如果单个服务出现问题,调用这个服务就会出现线程阻塞,此时若有大量的请求涌入,Servlet 容器的线程资源会被消耗完毕,导致服务瘫痪。服务与服务之间的依赖性,故障会传播,会对整个微服务系统造成灾难性的严重后果,这就是服务故障的 “雪崩” 效应。

1.在feign中使用:
Feign中自带熔断器:
    feign:
        hystrix:
            enabled: true
=====
service中指定fallback的类:
 @FeignClient(value = "hello-spring-cloud-service-admin", fallback = AdminServiceHystrix.class)
public interface AdminService {
   @RequestMapping(value = "hi", method = RequestMethod.GET)
   public String sayHi(@RequestParam(value = "message") String message);
 }
====
创建这个借口的实现类:
@Component
 public class AdminServiceHystrix implements AdminService {
 	@Override
 	public String sayHi(String message) {
   	 	return "Hi,your message is :"" + message + "" but request error.";
   	}
}     
2.在ribbon中使用:

pom.xml中加入:

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

​ 主函数中加入注解@EnableHystrix
​在service中使用:

@HystrixCommand(fallbackMethod = "hiError")
public String sayHi(String message) {
    return restTemplate.getForObject("http://HELLO-SPRING-CLOUD-SERVICE-ADMIN/hi?message=" + message, String.class);
}

public String hiError(String message) {
    return "Hi,your message is :"" + message + "" but request error.";
}

使用熔断仪器监控hystrix:

pom.xml中加入:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
@Configuration
public class HystrixDashboardConfiguration {

    @Bean
    public ServletRegistrationBean getServlet() {
        HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
        ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
        registrationBean.setLoadOnStartup(1);
        registrationBean.addUrlMappings("/hystrix.stream");
        registrationBean.setName("HystrixMetricsStreamServlet");
        return registrationBean;
    }
}

​ 测试熔断localhost:8764/hystrix

hystrix触发fallback的方法:、

​ timeout,SHORT_CIRCUITED:断路器打开不尝试执行,THREAD_POOL_REJECTED:线程池拒绝,不尝试执行,SEMAPHORE_REJECTED 信号量拒绝,不尝试执行 YES

使用统一的网关访问接口zuul:

​ 在 Spring Cloud 微服务系统中,一种常见的负载均衡方式是,客户端的请求首先经过负载均衡(Zuul、Ngnix),再到达服务网关(Zuul 集群),然后再到具体的服。 服务统一注册到高可用的服务注册中心集群,服务的所有的配置文件由配置服务管理,配置服务的配置文件放在 GIT 仓库,方便开发人员随时改配置

zuul:

​ Zuul 的主要功能是路由转发和过滤器。路由功能是微服务的一部分,比如 /api/user 转发到到 User 服务,/api/shop 转发到到 Shop 服务。Zuul 默认和 Ribbon 结合实现了负载均衡的功能。

pom.xml中加入:
<dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
 </dependency>
application.yml中书写配置文件:
spring:
  application:
    name: hello-spring-cloud-zuul

  server:
  port: 8769

  eureka:
  client:
    serviceUrl:
    defaultZone: http://localhost:8761/eureka/
  ##以/api/a/请求全部转发到ribbon服务中,以/api/b/全部转发到feign服务##
  zuul:
  routes:
    api-a:
    path: /api/a/**
    serviceId: hello-spring-cloud-web-admin-ribbon
    api-b:
    path: /api/b/**
    serviceId: hello-spring-cloud-web-admin-feign

​ 创建回调的类:主要是创建对对其出现错误后的回调机制:

主函数:
@SpringBootApplication
@EnableEurekaClient
@EnableZuulProxy
public class ZuulApplication {
    public static void main(String[] args) {
    	SpringApplication.run(ZuulApplication.class, args);
    }
}  

​ 其实就是聚合其他的服务:以上聚合了ribbon和feign两个服务。

分布式配置中心:

​ 有分布式配置中心组件 Spring Cloud Config ,它支持配置服务放在配置服务的内存中(即本地),也支持放在远程 Git 仓库中。在 Spring Cloud Config 组件中,分两个角色,一是 Config Server,二是 Config Client。

分布式配置中心服务端:
pom.xml中加入:
<?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>

    <parent>
        <groupId>com.funtl</groupId>
        <artifactId>hello-spring-cloud-dependencies</artifactId>
        <version>1.0.0-SNAPSHOT</version>
        <relativePath>../hello-spring-cloud-dependencies/pom.xml</relativePath>
    </parent>

    <artifactId>hello-spring-cloud-config</artifactId>
    <packaging>jar</packaging>

    <name>hello-spring-cloud-config</name>
    <url>http://www.funtl.com</url>
    <inceptionYear>2018-Now</inceptionYear>

    <dependencies>
        <!-- Spring Boot Begin -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- Spring Boot End -->

        <!-- Spring Cloud Begin -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-server</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
        <!-- Spring Cloud End -->
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <mainClass>com.funtl.hello.spring.cloud.config.ConfigApplication</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project> 

在ConfigApplication中开启:

@SpringBootApplication
@EnableConfigServer
@EnableEurekaClient
public class ConfigApplication {
   public static void main(String[] args) {
       SpringApplication.run(ConfigApplication.class, args);
  }
} 
在application.yml中书写配置文件:
spring:
  application:
    name: hello-spring-cloud-config
  cloud:
    config:
    label: master
    server:
      git:
      uri: https://github.com/topsale/spring-cloud-config
      search-paths: respo
      username:
      password:

  server:
  port: 8888

  eureka:
  client:
    serviceUrl:
    defaultZone: http://localhost:8761/eureka/

配置说明:

spring.cloud.config.label:配置仓库的分支

spring.cloud.config.server.git.uri:配置 Git 仓库地址(GitHub、GitLab、码云 ...)

spring.cloud.config.server.git.search-paths:配置仓库路径(存放配置文件的目录)

spring.cloud.config.server.git.username:访问 Git 仓库的账号

spring.cloud.config.server.git.password:访问 Git 仓库的密码

分布式配置中心客户端配置:
pom.xml中配置:
<?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>

    <parent>
        <groupId>com.funtl</groupId>
        <artifactId>hello-spring-cloud-dependencies</artifactId>
        <version>1.0.0-SNAPSHOT</version>
        <relativePath>../hello-spring-cloud-dependencies/pom.xml</relativePath>
    </parent>

    <artifactId>hello-spring-cloud-config-client</artifactId>
    <packaging>jar</packaging>

    <name>hello-spring-cloud-config-client</name>
    <url>http://www.funtl.com</url>
    <inceptionYear>2018-Now</inceptionYear>

    <dependencies>
        <!-- Spring Boot Begin -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- Spring Boot End -->

        <!-- Spring Cloud Begin -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
        <!-- Spring Cloud End -->
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <mainClass>com.funtl.hello.spring.cloud.config.client.ConfigClientApplication</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

入口类处理方式:

@SpringBootApplication
@EnableDiscoveryClient
public class ConfigClientApplication {
   public static void main(String[] args) {
          SpringApplication.run(ConfigClientApplication.class, args);
   }
}  
application.yml中书写配置文件:
spring:
  application:
    name: hello-spring-cloud-config-client
  cloud:
    config:
    uri: http://localhost:8888
    name: config-client
    label: master
    profile: dev

  server:
  port: 8889

  eureka:
  client:
    serviceUrl:
    defaultZone: http://localhost:8761/eureka/

配置说明:

spring.cloud.config.uri:配置服务中心的网址
​ spring.cloud.config.name:配置文件名称的前缀
​ spring.cloud.config.label:配置仓库的分支
​ spring.cloud.config.profile:配置文件的环境标识
​ dev:表示开发环境
​ test:表示测试环境
​ prod:表示生产环境

服务链路追踪:

这里主要使用ZipKin:
每个服务向 ZipKin 报告计时数据,ZipKin 会根据调用关系通过 ZipKin UI 生成依赖关系图,显示了多少跟踪请求通过每个服务,该系统让开发者可通过一个 Web 前端轻松的收集和分析数据,例如用户每次请求服务的处理时间等,可方便的监测系统中存在的瓶颈 。

说明:

​ 微服务架构是通过业务来划分服务的,使用 REST 调用。对外暴露的一个接口,可能需要很多个服务协同才能完成这个接口功能,如果链路上任何一个服务出现问题或者网络超时,都会形成导致接口调用失败。随着业务的不断扩张,服务之间互相调用会越来越复杂。

服务监控:

​ admin
​ 启动顺序:
​ config->eureka—>--->zipkin—>Admin—>serviceAdmin—>ZuulApplication

这就是简单的搭建,我们已经会用了,但是我们对各个组件还不是很深入,下面我们将会继续深入到各个组件,

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kay三石 [Alay Kay]

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值