详解“微服务”架构体系——SpringCloud Alibaba

微服务SpringCloud Alibaba架构 SpringCloud Alibaba微服务解决方案 概述 Spring Cloud Alibaba 是Spring Cloud的一个子项目,致力于提供微服务开发的一站式解决方案。此项目包含开发分布式应用微服务的必需组件,方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。依托 Spring Cloud Alibaba,您只需要添加一些注解和少量配置,就可以将 Spring Cloud 应用接入阿里微服务解决方案,通过阿里中间件来迅速搭建分布式应用系统。 核心组件分析 S 阅读详情

01 前言

"微服务”一词源于 Martin Fowler的名为 Microservices的,博文,可以在他的官方博客上找到http:/ /martinfowler . com/articles/microservices.html简单地说,微服务是系统架构上的一种设计风格,它的主旨是将一个原本独立的系统拆分成多个小型服务,这些小型服务都在各自独立的进程中运行,服务之间通过基于HTTP的 RESTfuL AP进行通信协作。常见微服务框架:Spring的spring cloud、阿里dubbo、华为ServiceComb、腾讯Tars、Facebook thrift、新浪微博Motan。本章节我们先从了解组成完整系统的各个组件开始,下章节将利用这些组件,搭建出一个完善的分布式系统。

1.1 Spring Cloud

这就不用多说了,官网有详细的介绍。

1.2 Spring Cloud Alibaba

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

主要组件
Sentinel:把流量作为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
Nacos:一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。
RocketMQ:一款开源的分布式消息系统,基于高可用分布式集群技术,提供低延时的、高可靠的消息发布与订阅服务。
Dubbo:Apache Dubbo™ 是一款高性能 Java RPC 框架。
Seata:阿里巴巴开源产品,一个易于使用的高性能微服务分布式事务解决方案。

02 服务注册与发现

Eureka:官方宣布2.x不再开源(闭源),之前的版本已经停止更新;也就说Eureka将来更多的技术提升已经没有了。所以,如果希望注册中心有更多强大功能的话,还需要另辟蹊径 。
Zookeeper:在企业级Zookeeper注册中心与 Dubbo组合比较多一些,kafka使用的也是,随着Eureka的停更,我们可以通过spring-cloud-starter-zookeeper-discovery这个启动器,将Zookeeper做为springcloud的注册中心。
Consul:go语言开发的,也是一个优秀的服务注册框架,使用量也比较多。
Nacos:来自于SpringCloudɵɹibaba,在企业中经过了百万级注册考验的,不但可以完美替换Eureka,还能做其他组件的替换,所以,Naocs也强烈建议使用。

2.1 介绍下Nacos用作注册中心

(1)Nacos简介

Nacos(Dynamic Naming and Configur ation Service) 是阿里巴巴2018年7月开源的项目,致力于发现、配置和管理微服务。

(2)Nacos安装

单节点

--下载镜像
docker pull nacos/nacos-server:1.3.1
--启动容器
docker run  --name nacos --env MODE=standalone --privileged=true  -p 8848:8848 --restart=always   -d dc833dc45d8f

访问:

http://127.0.0.1:8848/nacos 账号密码都是nacos

集群

安装前提

64 bit OS Linux/Unix/Mac,推荐使用Linux系统。
集群需要依赖mysql,单机可不必
3个或3个以上Nacos节点才能构成集群

(3)搭建Nacos高可用集群步骤:

1、需要去Nacos官网clone Nacos集群项目nacos-docker
2、nacos-docker是使用的Docker Compose对容器进行编排,所以首先需要安装Docker Compose详细信息可参照Nacos官网:https:/ /nacos.io/zh-cn/docs/quick-start-docker.html

1)安装Docker Compose
什么是Docker Compose
Compose项目是Docker官方的开源项目,负责实现对Docker容器集群的快速编排。

#在Linux下下载(下载到/usr/local/bin)
curl -L https://github.com/docker/compose/releases/download/1.25.0/run.sh > /usr/local/bin/docker-compose
# 设置文件可执行权限
chmod +x /usr/local/bin/docker-compose
# 查看版本信息
docker-compose --version

2)克隆Nacos-docker项目

#切换到自定义目录
cd /usr/local/nacos
#开始clone
git clone https://github.com/nacos-group/nacos-docker.git

3)运行nacos-docker脚本

#执行编排命令
docker-compose -f /usr/local/nacos/nacos-docker/example/cluster-hostname.yaml up

上面的编排命令主要下载mysql镜像和nacos镜像,自动完成镜像下载/容器启动
Pulling from nacos/nacos-mysql,版本是5. 7(执行初始化脚本)
Pulling nacos3 (nacos/nacos-server:latest)最新版本

4)停止、启动

#启动
docker-compose -f  /usr/local/nacos/nacos-docker/example/cluster-hostname.yaml start
#停止
docker-compose -f  /usr/local/nacos/nacos-docker/example/cluster-hostname.yaml stop

5)访问Nacos

http://192.168.1.1:8848/nacos
http://192.168.1.1:8849/nacos
http://192.168.1.1:8850/nacos

(4)Nacos快速入门

配置服务提供者

服务提供者可以通过 Nacos 的服务注册发现功能将其服务注册到 Nacos server 上。

添加nacos依赖

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    <version>${latest.version}</version>
</dependency>

添加配置

server.port=8070
spring.application.name=nacos-demo

spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848

启动类

@SpringBootApplication
@EnableDiscoveryClient
public class NacosProviderApplication {

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

	@RestController
	class EchoController {
		@RequestMapping(value = "/echo/{string}", method = RequestMethod.GET)
		public String echo(@PathVariable String string) {
			return "Hello Nacos Discovery " + string;
		}
	}
}

启动后,控制台:

说明注册成功,后台查看该服务:

下面我们用spring cloud 整合naocs实现服务调用

配置服务消费者

添加配置

server.port=8080
spring.application.name=service-consumer

spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848

添加启动类:服务消费者使用 @LoadBalanced RestTemplate 实现服务调用

@SpringBootApplication
@EnableDiscoveryClient
public class NacosConsumerApplication {

    @LoadBalanced
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

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

    @RestController
    public class TestController {

        private final RestTemplate restTemplate;

        @Autowired
        public TestController(RestTemplate restTemplate) {this.restTemplate = restTemplate;}

        @RequestMapping(value = "/echo/{str}", method = RequestMethod.GET)
        public String echo(@PathVariable String str) {
            return restTemplate.getForObject("http://service-provider/echo/" + str, String.class);
        }
    }
}

(5)测试

启动 ProviderApplication 和 ConsumerApplication ,调用 http://localhost:8080/echo/2018,返回内容为 Hello Nacos Discovery 2018。

03 分布式配置中心解决方案与应用

目前市面上用的比较多的配置中心有(时间顺序)
Disconf:2014年7月百度开源的配置管理中心,同样具备配置的管理能力,不过目前已经不维护了,最近的一次提交是4-5年前了。
Spring Cloud Config:2014年9月开源,Spring Cloud 生态组件,可以和Spring Cloud体系无缝整合。
Apollo:2016年5月,携程开源的配置管理中心,具备规范的权限、流程治理等特性。
Nacos:2018年6月,阿里开源的配置中心,也可以做DNS和RPC的服务发现

3.1 介绍下Nacos用作分布式配置中心

启动了 Nacos server 后,您就可以参考以下示例代码,为您的 Spring Cloud 应用启动 Nacos 配置管理服务了。完整示例代码请参考:nacos-spring-cloud-config-example

  1. 添加依赖:
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    <version>${latest.version}</version>
</dependency>

注意:版本 2.1.x.RELEASE 对应的是 Spring Boot 2.1.x 版本。版本 2.0.x.RELEASE 对应的是 Spring Boot 2.0.x 版本,版本 1.5.x.RELEASE 对应的是 Spring Boot 1.5.x 版本。

更多版本对应关系参考:版本说明 Wiki

  1. 在 bootstrap.properties 中配置 Nacos server 的地址和应用名
spring.cloud.nacos.config.server-addr=127.0.0.1:8848

spring.application.name=example

说明:之所以需要配置 spring.application.name ,是因为它是构成 Nacos 配置管理 dataId字段的一部分。

在 Nacos Spring Cloud 中,dataId 的完整格式如下:

${prefix}-${spring.profiles.active}.${file-extension}
  • prefix 默认为 spring.application.name 的值,也可以通过配置项 spring.cloud.nacos.config.prefix来配置。
  • spring.profiles.active 即为当前环境对应的 profile,详情可以参考 Spring Boot文档。 注意:当 spring.profiles.active 为空时,对应的连接符 - 也将不存在,dataId 的拼接格式变成 ${prefix}.${file-extension}
  • file-exetension 为配置内容的数据格式,可以通过配置项 spring.cloud.nacos.config.file-extension 来配置。目前只支持 properties 和 yaml 类型。
  1. 通过 Spring Cloud 原生注解 @RefreshScope 实现配置自动更新:
@RestController
@RequestMapping("/config")
@RefreshScope
public class ConfigController {

    @Value("${useLocalCache:false}")
    private boolean useLocalCache;

    @RequestMapping("/get")
    public boolean get() {
        return useLocalCache;
    }
}
  1. 首先通过调用 Nacos Open API 向 Nacos Server 发布配置:dataId 为example.properties,内容为useLocalCache=true
curl -X POST "http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=example.properties&group=DEFAULT_GROUP&content=useLocalCache=true"
  1. 运行 NacosConfigApplication,调用 curl http://localhost:8080/config/get,返回内容是 true。
  2. 再次调用 Nacos Open API 向 Nacos server 发布配置:dataId 为example.properties,内容为useLocalCache=false
curl -X POST "http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=example.properties&group=DEFAULT_GROUP&content=useLocalCache=false"
  1. 再次访问 http://localhost:8080/config/get,此时返回内容为false,说明程序中的useLocalCache值已经被动态更新了。

04 分布式服务调用

4.1 RPC概述

RPC 的主要功能目标是让构建分布式计算(应用)更容易,在提供强大的远程调用能力时不损失本地调用的语义简洁性。为实现该目标,RPC 框架需提供一种透明调用机制,让使用者不必显式的区分本地调用和远程调用。

RPC的优点:分布式设计、部署灵活、解耦服务、扩展性强。

4.2 RPC框架

Dubbo:国内最早开源的 RPC 框架,由阿里巴巴公司开发并于 2011 年末对外开源,仅支持 Java 语言。
Motan:微博内部使用的 RPC 框架,于 2016 年对外开源,仅支持 Java 语言。
Tars:腾讯内部使用的 RPC 框架,于 2017 年对外开源,仅支持 C++ 语言。
Spring Cloud:国外 Pivotal 公司 2014 年对外开源的 RPC 框架,提供了丰富的生态组件。
gRPC:Google 于 2015 年对外开源的跨语言 RPC 框架,支持多种语言。
Thrift:最初是由 Facebook 开发的内部系统跨语言的 RPC 框架,2007 年贡献给了 Apache 基金,成为
Apache:开源项目之一,支持多种语言。

4.3 RPC框架优点

RPC框架一般使用长链接,不必每次通信都要3次握手,减少网络开销。
RPC框架一般都有注册中心,有丰富的监控管理发布、下线接口、动态扩展等,对调用方来说是无感知、统一化的操作协议私密,安全性较高
RPC 协议更简单内容更小,效率更高,服务化架构、服务化治理,RPC框架是一个强力的支撑。

4.4 RPC框架应用:使用Spring Cloud Alibaba 整合Dubbo实现

由于 Dubbo Spring Cloud 构建在原生的 Spring Cloud 之上, 其服务治理方面的能力可认为是 Spring Cloud Plus,不仅完全覆盖 Spring Cloud 原生特性,而且提供更为稳定和成熟的实现,特性比对如下表所示:

4.5 Dubbo 作为 Spring Cloud 服务调用

默认情况,Spring Cloud Open Feign 以及@LoadBalanced`RestTemplate 作为 Spring Cloud 的两种服务调用方式。 Dubbo Spring Cloud 为其提供了第三种选择,即 Dubbo 服务将作为 Spring Cloud 服务调用的同等公民出现,应用可通过 Apache Dubbo 注解@Service 和@Reference 暴露和引用 Dubbo 服务,实现服务间多种协议的通讯。同时,也可以利用 Dubbo 泛化接口轻松实现服务网关。

4.6 快速上手

按照传统的 Dubbo 开发模式,在构建服务提供者之前,第一个步骤是为服务提供者和服务消费者定义 Dubbo 服务接口。
为了确保契约的一致性,推荐的做法是将 Dubbo 服务接口打包在第二方或者第三方的 artifact(jar)中,该 artifact 甚至无需添加任何依赖。
对于服务提供方而言,不仅通过依赖 artifact 的形式引入 Dubbo 服务接口,而且需要将其实现。对应的服务消费端,同样地需要依赖该 artifact,并以接口调用的方式执行远程方法。接下来的步骤则是创建 artifact。

4.7 创建服务API

创建一个api模块,专门写各种接口的:

/**
 * @author 原
 * @date 2020/12/8
 * @since 1.0
 **/
public interface TestService {

    String getMsg();
}

4.8 创建服务提供者

导入依赖

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
            <version>2.2.2.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-dubbo</artifactId>
        </dependency>
        <!-- api接口的依赖包-->
        <dependency>
            <groupId>com.dubbo.demo</groupId>
            <artifactId>dubbo-demo-api</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
    </dependencies>

编写配置

dubbo:
	scan:
	# dubbo 服务扫描基准包
		base-packages: org.springframework.cloud.alibaba.dubbo.bootstrap
	protocol:
	# dubbo 协议
		name: dubbo
		# dubbo 协议端口( -1 表示自增端口,从 20880 开始)
		port: -1
	spring:
		cloud:
			nacos:
			# Nacos 服务发现与注册配置
			discovery:
				server-addr: 127.0.0.1:8848实现
/**
 * @author 原
 * @date 2021/1/28
 * @since 1.0
 **/
@Service//dubbo的service注解
public class TestServiceImpl implements TestService {
    @Override
    public String getMsg() {
        return "123123";
    }
}

启动类

/**
 * @author 原
 * @date 2021/1/28
 * @since 1.0
 **/
@SpringBootApplication
@EnableDiscoveryClient
public class DubboProviderApplication {
    public static void main(String[] args) {
        SpringApplication.run(DubboProviderApplication.class,args);
    }
}

4.9 创建服务消费者

除了api的实现类 其他复用提供者的代码

编写测试类

/**
 * @author 原
 * @date 2021/1/28
 * @since 1.0
 **/
@RestController
public class TestController {

    @Reference
    TestService testService;

    @GetMapping("/dubbo/test")
    public String getMsg(){
        return testService.getMsg();
    }
}

访问:

返回111

05 服务流量管理

5.1 为什么要流控降级?

流量是非常随机性的、不可预测的。前一秒可能还风平浪静,后一秒可能就出现流量洪峰了(例如双十一零点的场景)。然而我们系统的容量总是有限的,如果突然而来的流量超过了系统的承受能力,就可能会导致请求处理不过来,堆积的请求处理缓慢,CPU/Load飙高,最后导致系统崩溃。因此,我们需要针对这种突发的流量来进行限制,在尽可能处理请求的同时来保障服务不被打垮,这就是流量控制。

一个服务常常会调用别的模块,可能是另外的一个远程服务、数据库,或者第三方API 等。例如,支付的时候,可能需要远程调用银联提供的 API;查询某个商品的价格,可能需要进行数据库查询。然而,这个被依赖服务的稳定性是不能保证的。如果依赖的服务出现了不稳定的情况,请求的响应时间变长,那么调用服务的方法的响应时间也会变长,线程会产生堆积,最终可能耗尽业务自身的线程池,服务本身也变得不可用。

现代微服务架构都是分布式的,由非常多的服务组成。不同服务之间相互调用,组成复杂的调用链路。以上的问题在链路调用中会产生放大的效果。复杂链路上的某一环不稳定,就可能会层层级联, 最终导致整个链路都不可用。 因此我们需要对不稳定的弱依赖服务进行熔断降级,暂时切断不稳定调用,避免局部不稳定因素导致整体的雪崩。

关于容错组件的停更/升级/替换

服务降级:
Hystrix:官网不极力推荐,但是中国企业中还在大规模使用,对于限流和熔断降级虽然在1 .5版本官方还支持(版本稳定),
但现在官方已经开始推荐大家使用Resilience4j
Resilience4J:官网推荐使用,但是国内很少用这个。
Sentienl:来自于Spring Cloud Alibaba,在中国企业替换Hystrix的组件,国内强烈建议使用

这里就主要介绍下Sentinel。

5.2 Sentinel介绍

Sentinel是阿里开源的项目,提供了流量控制、熔断降级、系统负载保护等多个维度来保障服务之间的稳定性。
Sentinel的流控操作起来非常简单,在控制台进行配置即可看见效,所见即所得

Sentinel 具有以下特征:

  • 丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
  • 完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
  • 广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。
  • 完善的 SPI 扩展点:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。

官网

https://github.com/alibaba/Sentinel
中文
https://github.com/alibaba/Sentinel/wiki/%E4%BB%8B%E7%BB%8D
https://sentinelguard.io/zh-cn/docs/introduction.html

Sentinel 的使用可以分为两个部分:
核心库(Java 客户端):不依赖任何框架/库,能够运行于 Java 7 及以上的版本的运行时环境,同时对Dubbo / Spring Cloud 等框架也有较好的支持。
控制台(Dashboard):控制台主要负责管理推送规则、监控、集群限流分配管理、机器发现等

使用场景

 在服务提供方(Service Provider)的场景下,我们需要保护服务提供方自身不被流量洪峰打垮。 这时候通常根据服务提供方的服务能力进行流量控制, 或针对特定的服务调用方进行限制。我们可以结合前期压测评估核心口的承受能力,配置 QPS 模式的限流,当每秒的请求量超过设定的阈值时,会自动拒绝多余的请求。

 为了避免调用其他服务时被不稳定的服务拖垮自身,我们需要在服务调用端(Service Consumer)对不稳定服务依赖进行隔离和熔断。手段包括信号量隔离、异常比例降级、RT 降级等多种手段。

 当系统长期处于低水位的情况下, 流量突然增加时, 直接把系统拉升到高水位可能瞬间把系统压垮。这时候我们可以借助 Sentinel 的 WarmUp 流控模式控制通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,而不是在一瞬间全部放行。这样可以给冷系统一个预热的时间,避免冷系统被压垮。

 利用 Sentinel 的匀速排队模式进行“削峰填谷”, 把请求突刺均摊到一段时间内, 让系统负载保持在请求处理水位之内,同时尽可能地处理更多请求。

 利用 Sentinel 的网关流控特性,在网关入口处进行流量防护,或限制 API 的调用频率。

5.2 Sentinel安装

1、下载jar包https://github.com/alibaba/Sentinel/releases

2、启动

java -Dserver.port=8787 -Dcsp.sentinel.dashboard.server=127.0.0.1:8787 -Dproject.name=sentinel-dashboard -jar /home/sentinel/sentinel-dashboard-1.8.0.jar

3、访问

http://127.0.0.1:8787/#/login

初始账号密码sentinel/sentinel

可以看到sentinel是自己本身的监控

5.3 sentinel快速入门

1、导入依赖

<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-core</artifactId>
    <version>1.8.0</version>
</dependency>

2、测试类

public class TestService {

    public static void main(String[] args) {
        initFlowRules();
        while (true) {
            Entry entry = null;
            try {
                entry = SphU.entry("HelloWorld");
                /*您的业务逻辑 - 开始*/
                System.out.println("hello world");
                /*您的业务逻辑 - 结束*/
            } catch (BlockException e1) {
                /*流控逻辑处理 - 开始*/
                System.out.println("block!");
                /*流控逻辑处理 - 结束*/
            } finally {
                if (entry != null) {
                    entry.exit();
                }
            }
        }
    }

    //设置流量控制规则 设置当QPS达到20时 会限制流量(抛出异常,可以执行处理)
    private static void initFlowRules(){
        List<FlowRule> rules = new ArrayList<>();
        FlowRule rule = new FlowRule();
        rule.setResource("HelloWorld");
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        // Set limit QPS to 20.
        rule.setCount(20);
        rules.add(rule);
        FlowRuleManager.loadRules(rules);
    }
}

执行结果:

可以看到,这个程序每秒稳定输出 "hello world" 20 次,和规则中预先设定的阈值是一样的。 block表示被阻止的请求。

官方使用文档:https://github.com/alibaba/Sentinel/wiki/如何使用

5.4 Sentinel整合SpringCloud实现服务限流/熔断

导入依赖

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
    </dependencies>

配置

server.port=8082
spring.application.name=sentinel-demo
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
spring.cloud.sentinel.transport.dashboard=127.0.0.1:8787
//在需要流控的方法加上@SentinelResource
@RestController
public class TestController {

    @GetMapping("/sentinel")
    @SentinelResource
    public String getMsg(){
        return "11";
    }
}

启动应用,访问http://127.0.0.1:8082/sentinel后去sentinel后台

下面我们来配一条最简单的流控规则。针对 sentinel_spring_web_context /sentinel 这个服务调用配置限流规则(需要有过访问量才能看到)。我们配一条 QPS 为 1的流控规则,这代表针对该服务方法的调用每秒钟不能超过 1 次,超出会直接拒绝。

现在快速访问:http://localhost:8082/sentinel

查看实时监控页面:

其他功能的使用,大家可以参考官方文档自行摸索。

5.5 如何选择流控降级组件?

以下是 Sent inel 与其它fault-tolerance 组件的对比:

06 分布式事务

6.1 为什么需要分布式事务?

分布式事务是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。简单来说就是组成事务的各个单元处于不同数据库服务器上。 如何保证服务间的一致性?当在一条较长的微服务调用链中, 位于中间位置的微服务节点出现异常,如何保证整个服务的数据一致性?分布式一致性的引入, 一定不可避免带来性能问题, 如何更高效的解决分布式一致性问题,一直是我们致力于解决此问题的关键出发点。

6.2 分布式事务解决方案分类

刚性事务

刚性事务指的就是遵循本地事务四大特性(ACID)的强一致性事务。它的特点就是强一致性,要求组成事务的各个单元马上提交或者马上回滚,没有时间弹性,要求以同步的方式执行。通常在单体架构项目中应用较多,一般都是企业级应用(或者局域网应用)。例如:生成合同时记录日志,付款成功后生成凭据等等。但是,在时下流行的互联网项目中,这种刚性事务来解决分布式事务就会有很多的弊端。其中最明显的或者说最致命的就是性能问题。

因为某个参与者不能自己提交事务,必须等待所有参与者执行OK了之后,一起提交事务,那么事务锁住的时间就变得非常长,从而导致性能非常低下。基于此我们也就得出了一个结论,阶段越多,性能越差。

柔性事务

柔性事务是针对刚性事务而说的,我们刚才分析了刚性事务,它有两个特点,第一个强一致性,第二个近实时性(NRT)。而柔性事务的特点是不需要立刻马上执行(同步性),且不需要强一致性。它只要满足基本可用和最终一致就可以了。要想真正的明白,需要从BASE理论和CAP理论说起。

6.3 CAP理论和BASE理论

1)CAP理论
CAP理论,又叫做CAP原则,网上对他的概念描述非常的清晰,且一致。换句话说,我们在网上搜到的CAP理论的描述,基本都是一样的。它的描述是这样的:
CAP指的是在一个分布式系统中,一致性(Consistency)、可用性(Availability)、分区容错性(Partitiontolerance)。其中,C,A,P的说明如下:
一致性(C):在分布式系统中的所有数据备份,在同一时刻是否同样的值。(等同于所有节点访问同一份最新的数据副本)
可用性(A):在集群中一部分节点故障后,集群整体是否还能响应客户端]的读写请求。(对数据更新具备高可用性)
分区容错性(P):以实际效果而言,分区相当于对通信的时限要求。系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作在C和A之间做出选择。

CAP原则指的是,这三个要素最多只能同时实现两点,不可能三者兼顾。因此在进行分布式架构设计时,必须做出取舍。而对于分布式数据系统,分区容错性是基本要求,否则就失去了价值。因此设计分布式数据系统,就是在一致性和可用性之间取一个平衡。对于大多数web应用,其实并不需要强一致性,因此牺牲一致性而换取高可用性,是目前多数分布式数据库产品的方向。

2)BASE理论
BASE理论是指,Basically Available(基本可用)、Soft-state( 软状态/柔性事务)、Eventual Consistency(最
终一致性)。
1、基本可用 BA:(Basically Available ):
指分布式系统在出现故障的时候,允许损失部分可用性,保证核心可用。但不等价于不可用。比如:搜索引擎0.5秒返回查询结果,但由于故障,2秒响应查询结果;网页访问过大时,部分用户提供降级服务等。简单来说就是基本可用。
2、软状态 S:( Soft State):
软状态是指允许系统存在中间状态,并且该中间状态不会影响系统整体可用性。即允许系统在不同节点间副本同步的时候存在延时。简单来说就是状态可以在一段时间内不同步。
3、最终一致性 E:(Eventually Consistent ):

系统中的所有数据副本经过一定时间后,最终能够达到一致的状态,不需要实时保证系统数据的强一致性。最终一致性是弱一致性的一种特殊情况。BASE理论面向的是大型高可用可扩展的分布式系统,通过牺牲强一致性来获得可用性。ACID是传统数据库常用的概念设计,追求强一致性模型。简单来说就是在一定的时间窗口内, 最终数据达成一致即可。

BASE理论是基于CAP原则演化而来,是对CAP中一致性和可用性权衡的结果。

核心思想:即使无法做到强一致性,但每个业务根据自身的特点,采用适当的方式来使系统达到最终一致性。

6.4 分布式事务解决方案

(1)二阶段提交2PC(3PC)

关于更多2pc与3pc的介绍,可以参考博文:2PC和3PC原理,这不是我们今天讨论的重点。

(2)XA

XA 标准提出后的 20 多年间未能得到持续的演进,在学术界有协议优化和日志协同处理等相关的研究,在工业界使用 XA 落地方案的相对较少,主要集中在应用服务器的场景。XA 方案要求相关的厂商提供其具体协议的实现,目前大部分关系数据库支持了 XA 协议,但是支持程度不尽相同,例如,MySQL 在 5.7 才对 xa_prepare 语义做了完整支持。XA 方案被人诟病的是其性能, 其实更为严重的是对于连接资源的占用, 导致在高并发未有足够的连接资源来响应请求成为系统的瓶颈。在微服务架构下 XA 事务方案随着微服务链路的扩展成为一种反伸缩模式,进一步加剧了资源的占用。另外 XA 事务方案要求事务链路中的 resource 全部实现 XA 协议方可使用,若其中某一资源不满足,那么就无法保证整个链路的数据一致性。

(3)TCC补偿方案

TCC分别指的是Try,Confirm,Cancel。它是补偿型分布式事务解决方案。何为补偿呢?其实我们把TCC这3个部分分别做什么捋清楚,就很容理解了。首先,我们先来看下它们的主要作用:

Try 阶段主要是对业务系统做检测及资源预留。
Confirm 阶段主要是对业务系统做确认提交,Try阶段执行成功并开始执行 Confirm阶段时,默认 Confirm阶段是
不会出错的。即:只要Try成功,Confirm一定成功。
Cancel 阶段主要是在业务执行错误,需要回滚的状态下执行的业务取消,预留资源释放。

由此,我们可以得出结论,就是在Try阶段进行尝试提交事务,当Try执行OK了,Confirm执行,且默认认为它一定成功。但是当Try提交失败了,则由Cancel处理回滚和资源释放。

从概念上 TCC 框架可以认为是一种万能框架,但是其难点是业务对于这三个接口的实现,开发成本相对较高,有较多业务难以做资源预留相关的逻辑处理, 以及是否需要在预留资源的同时从业务层面来保证隔离性。因此,这种模式比较适应于金融场景中易于做资源预留的扣减模型。

(4) Saga

Saga其实是30年前的一篇数据库论文里提到的一个概念。在论文中一个Saga事务就是一个长期运行的事务,这个事务是由多个本地事务所组成, 每个本地事务有相应的执行模块和补偿模块,当saga事务中的任意一个本地事务出错了, 可以通过调用相关事务对应的补偿方法恢复,达到事务的最终一致性。

有了 TCC 解决方案为什么还需要 Saga 事务解决方案?上文提到了 TCC 方案中对业务的改造成本较大, 对于内部系统可以自上而下大刀阔斧的推进系统的改造, 但对于第三方的接口的调用往往很难推动第三方进行 TCC 的改造,让对方为了你这一个用户去改造 TCC 方案而其他用户并不需要,需求上明显也是不合理的。要求第三方业务接口提供正反接口比如扣款和退款,在异常场景下必要的数据冲正是合理的。另外,Saga 方案更加适应于工作流式的长事务方案并且可异步化。

(5)最终一致性方案

本地消息表

这种实现方式应该是业界使用最多的,其核心思想是将分布式事务拆分成本地事务进行处理,这种思路是来源于
ebay。它和MQ事务消息的实现思路都是一样的,都是利用MQ通知不同的服务实现事务的操作。不同的是,针对
消息队列的信任情况,分成了两种不同的实现。本地消息表它是对消息队列的稳定性处于不信任的态度,认为消息
可能会出现丢失,或者消息队列的运行网络会出现阻塞,于是在数据库中建立一张独立的表,用于存放事务执行的
状态,配合消息队列实现事务的控制。

MQ事务消息

有一些第三方的MQ是支持事务消息的,比如RocketMQ,ActiveMQ,他们支持事务消息的方式也是类似于采用的
二阶段提交。但是有一些常用的MQ也不支持事务消息,比如 RabbitMQ 和 Kafka 都不支持。
以阿里的 RocketMQ 中间件为例,其思路大致为:
第一阶段Prepared消息,会拿到消息的地址。
第二阶段执行本地事务。
第三阶段通过第一阶段拿到的地址去访问消息,并修改状态。
也就是说在业务方法内要想消息队列提交两次请求,一次发送消息和一次确认消息。如果确认消息发送失败了
RocketMQ会定期扫描消息集群中的事务消息,这时候发现了Prepared消息,它会向消息发送者确认,所以生产方需要实现一个check接口,RocketMQ会根据发送端设置的策略来决定是回滚还是继续发送确认消息。这样就保证了消息发送与本地事务同时成功或同时失败。

用一个下单业务流程图来表示下:

两者对比

6.5 分布式事务框架Seata

FESCAR是阿里巴巴 开源的分布式事务中间件,以高效并且对业务0侵入的方式,解决微服务场景下面临的分布式
事务问题。Seata是fescar的升级版本,从2019年4月起,更名为seata。

(1)seata的典型案例分析

在seata的官方网站中提供了一套详细的业务流程介绍,我们就以此为例,展开讲解。

首先是单体架构的事务场景介绍:电商购物中的3个业务模块(库存、订单和账户)。他们操作本地数据库,由于
同库同源,所以本地事务可以保证其一致性,如下图所示:

但是在微服务架构中,由于每个业务模块变成了独立的服务,且每个服务连接自己的数据库,此时由原来同库同源
变成了不同数据库不同数据源的情况,虽然每个服务自己的数据库操作仍然可以使用本地事务控制,但是要让服务
间的事务保持一致性就需要用到分布式事务了。

在此时,引入了seata,它提供了一个“完美”的解决方案。如下图所示:

在图中的三个和seata相关的组件,前面在介绍fescar的时候已经介绍了,它也是seata的基本组件,他们分别是:
1)事务协调器(TC):维护全局和分支事务的状态,驱动全局提交或回滚。
2)事务管理器(TM):定义全局事务的范围:开始全局事务,提交或回滚全局事务。
3)资源管理器(RM):管理分支事务的资源,与TC通信以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。

seata管理分布式事务的生命周期

  1. TM要求TC开始新的全局事务。 TC生成表示全局事务的XID。
  2. XID通过微服务的调用链传播。
  3. RM将本地事务注册为XID到TC的相应全局事务的分支。
  4. TM要求TC提交或回滚XID的相应全局事务。
  5. TC在XID的相应全局事务下驱动所有分支事务,以完成分支提交或回滚。

库存服务

public interface StorageService {

    /**
     * deduct storage count
     */
    void deduct(String commodityCode, int count);
}

订单服务

public interface OrderService {

    /**
     * create order
     */
    Order create(String userId, String commodityCode, int orderCount);
}

账户服务

public interface AccountService {

    /**
     * debit balance of user's account
     */
    void debit(String userId, int money);
}

主业务逻辑

public class BusinessServiceImpl implements BusinessService {

    private StorageService storageService;

    private OrderService orderService;

    /**
     * purchase
     */
    public void purchase(String userId, String commodityCode, int orderCount) {

        storageService.deduct(commodityCode, orderCount);

        orderService.create(userId, commodityCode, orderCount);
    }
}
public class OrderServiceImpl implements OrderService {

    private OrderDAO orderDAO;

    private AccountService accountService;

    public Order create(String userId, String commodityCode, int orderCount) {

        int orderMoney = calculate(commodityCode, orderCount);

        accountService.debit(userId, orderMoney);

        Order order = new Order();
        order.userId = userId;
        order.commodityCode = commodityCode;
        order.count = orderCount;
        order.money = orderMoney;

        // INSERT INTO orders ...
        return orderDAO.insert(order);
    }
}

我们只需要一个@GlobalTransactional关于业务方法的注释:

    @GlobalTransactional
    public void purchase(String userId, String commodityCode, int orderCount) {
        ......
    }

6.6 由Dubbo + SEATA提供支持的示例

(1)步骤1:建立资料库

  • 要求:具有InnoDB引擎的MySQL。

注意:实际上,在示例用例中,这3个服务应该有3个数据库。但是,为了简单起见,我们只能创建一个数据库并配置3个数据源。

使用您刚创建的数据库URL /用户名/密码修改Spring XML。

dubbo-account-service.xml dubbo-order-service.xml dubbo-storage-service.xml

        <property name="url" value="jdbc:mysql://x.x.x.x:3306/xxx" />
        <property name="username" value="xxx" />
        <property name="password" value="xxx" />

(2)步骤2:创建UNDO_LOG表

UNDO_LOG SEATA AT模式需要此表。

-- 注意此处0.3.0+ 增加唯一索引 ux_undo_log
CREATE TABLE `undo_log` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `branch_id` bigint(20) NOT NULL,
  `xid` varchar(100) NOT NULL,
  `context` varchar(128) NOT NULL,
  `rollback_info` longblob NOT NULL,
  `log_status` int(11) NOT NULL,
  `log_created` datetime NOT NULL,
  `log_modified` datetime NOT NULL,
  `ext` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

(3)步骤3:建立表格,例如业务

DROP TABLE IF EXISTS `storage_tbl`;
CREATE TABLE `storage_tbl` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `commodity_code` varchar(255) DEFAULT NULL,
  `count` int(11) DEFAULT 0,
  PRIMARY KEY (`id`),
  UNIQUE KEY (`commodity_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


DROP TABLE IF EXISTS `order_tbl`;
CREATE TABLE `order_tbl` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` varchar(255) DEFAULT NULL,
  `commodity_code` varchar(255) DEFAULT NULL,
  `count` int(11) DEFAULT 0,
  `money` int(11) DEFAULT 0,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


DROP TABLE IF EXISTS `account_tbl`;
CREATE TABLE `account_tbl` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` varchar(255) DEFAULT NULL,
  `money` int(11) DEFAULT 0,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

(4)步骤4:启动服务器

  • 从https://github.com/seata/seata/releases下载服务器软件包,将其解压缩。
Usage: sh seata-server.sh(for linux and mac) or cmd seata-server.bat(for windows) [options]
  Options:
    --host, -h
      The host to bind.
      Default: 0.0.0.0
    --port, -p
      The port to listen.
      Default: 8091
    --storeMode, -m
      log store mode : file、db
      Default: file
    --help

e.g.

sh seata-server.sh -p 8091 -h 127.0.0.1 -m file

(5)步骤5:运行示例

前往样品仓库:seata-samples

  • 启动DubboAccountServiceStarter
  • 启动DubboStorageServiceStarter
  • 启动DubboOrderServiceStarter
  • 运行DubboBusinessTester进行演示测试

TBD:用于运行演示应用程序的脚本

 

细解“微服务”架构体系——SpringCloud Alibaba! "微服务”一词源于 Martin Fowler的名为 Microservices的,博文,可以在他的官方博客上找到http:/ /martinfowler . com/articles/microservices.html简单地说,微服务是系统架构上的一种设计风格,它的主旨是将一个原本独立的系统拆分成多个小型服务,这些小型服务都在各自独立的进程中运行,服务之间通过基于HTTP的 RESTfuL AP进行通信协作。 阅读详情

相关推荐

【云原生】SpringCloud Alibaba 之 Nacos注册中心实战

什么是 Spring Cloud Alibaba,Nacos又是什么,快速入门Naocs!

wanghuichen的博客 6319

Spring Cloud Alibaba微服务架构简介

Spring Cloud Alibaba 是阿里巴巴提供的开发一站式解决方案,是阿里巴巴开源中间件与 Spring Cloud 体系的融合。此项目包含开发分布式应用微服务的必需组件,方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。依托Spring Cloud Alibaba,您只需要添加一些注解和少量配置,就可以将 Spring Cloud 应用接入阿里微服务解决方案,通过阿里中间件来迅速搭建分布式应用系统。

DN金猿的博客 4333

GPD源码分析

gpd使用示例 先看下面一段代码,为标准gpd算法的使用方法,可以看到输入为点云,cloud_camera_; 输入:std::unique_ptr<gpd::util::Cloud> cloud_camera_ 输出: std::vector<std::unique_ptr<gpd::candidate::Hand>> grasps; // detect grasp poses gpd对象:std::unique_ptr<gpd::GraspDetect.

weixin_41003113的博客 2334

Spring Boot 中如何使用 Spring Cloud Alibaba 实现微服务治理

本文介绍了如何在 Spring Boot 中使用 Spring Cloud Alibaba 实现微服务治理,包括服务注册与发现、配置中心、流量管理、熔断降级等功能。Spring Cloud Alibaba 提供了一套完整的微服务治理解决方案,可以帮助我们有效地管理和保护微服务架构,提高系统的稳定性和可用性。

it_xushixiong的博客 2152

别再混淆了!5分钟搞懂机器人导纳控制与阻抗控制的本质区别(附Simulink对比仿真)

本文深入解析机器人柔顺控制中的导纳控制与阻抗控制的本质区别,通过信号流方向、架构对比和应用场景三个关键视角进行详细阐述。文章还提供Simulink对比仿真案例,帮助读者快速理解两种控制策略的差异及其适用场景,特别适合机器人控制领域的研究者和工程师参考。

weixin_42543046的博客 604

S4 Hana SD -信贷管理 - 03

自动信用控制将针对同一信用控制范围的不同的客户风险类别和信贷组执行不同的信用控制政策。对于ECC系统而言,无需单独设置检查规则,可在自动信贷控制进行设置即可,如图1-5-2。在S4 HANA版本中,自动信贷控制和检查规则是分离的。S4系统需要在定义自动信贷控制的时候,给字段“SAP信用管理”打钩,激活检查规则,然后需要单独在检查规则页签设置检查规则。接下来,我们分别介绍ECC和S4 HANA系统中两种不同配置方式.6.2SPRO。

weixin_46525734的博客 2888

Spring Cloud Alibaba简书(一)------微服务介绍

微服务介绍 1.1 系统架构演变 随着互联网的发展,网站应用的规模也在不断的扩大,进而导致系统架构也在不断的进行变化。 从互联网早起到现在,系统架构大体经历了下面几个过程: 单体应用架构—>垂直应用架构—>分布式架构—>SOA架构—>微服务架构,当然还有悄然兴起的Service Mesh(服务网格化)。 接下来我们就来了解一下每种系统架构是什么样子的, 以及各有什么优缺点。 1.1.1 单体应用架构 互联网早期,一般的网站应用流量较小,只需一个应用,将所有功能代码都部署在一起就可以,

ruiace的博客 2875

OCEAN 电路仿真

介绍利用 Cadence OCEAN 进行电路脚本仿真的方法

weixin_43249158的博客 4402

springcloudAlibaba整合Openfeign远程接口调用

springcloudAlibaba整合Openfeign远程接口调用 Feign 是一个声明式网络服务客户端,它使得书写网络服务器更加简单。通过使用Feign创建一个接口并且对他进行声明。 1.新定义一个order-openFeign子模块项目,在pom.xml文件当中引入openfeign依赖。因为我们在主模块中定义好了版本号,所以无需添加。如有问题可以查看往期博客。 2.我们新创建一个feign包,在包下定义一个stockFeignService接口,在类上面添加@FeignClient客户端,指定

摆渡人一直都在 913

北斗导航 | 从北一到北二再到北三,你应该知道的北斗导航系统

博主github:https://github.com/MichaelBeechan 博主优快云:https://blog.youkuaiyun.com/u011344545 一、引言 我国高度重视北斗系统的建设和发展。自20世纪80年代开始探索适合我们国家国情的卫星导航系统发展道路,形成了“三步走”的发展战略:2000年底,建成北斗一号导航系统,向我国广大用户提供服务;2012年底,建成北斗二号导航系统,...

尘世冰封的专栏 3079

2026年全国青少年信息素养大赛复赛真题(算法应用主题赛C++小学组:带解析)(7月4日试卷一)【文末附答案和解析】

2026年全国青少年信息素养大赛复赛真题(算法应用主题赛C++小学组:带解析)(7月4日试卷一)【文末附答案和解析】

王老师青少年编程 1738

【SpringCloud Alibaba】 介绍及微服务模块搭建

Spring Cloud Alibaba致力于提供微服务开发的一站式解决方案。此项目包含开发分布式应用微服务的必需组件,方便开发者通过Spring Cloud编程模型轻松使用这些组件来开发分布式应用服务。 依托Spring Cloud Alibaba ,只需要添加一些注解和少量配置,就可以将Spring Cloud应用接入阿里微服务解决方案,通过阿里中间件来迅速搭建分布式应用系统。

阿Q的小窝 1万+

Lumerical 教程目录,说明及个人感悟(共计138篇,持续更新中)

Lumerical---教程说明及个人感悟

u011699626的博客 1万+

SpringCloud Alibaba 从入门到精通(精选)

SpringCloud Alibaba 从入门到精通 一. 课程介绍 1.1 课程导学 什么是SpringCloudAlibaba? 阿里巴巴结合自身微服务实践,开源的微服务全家桶 在Spring Cloud项目中孵化,很可能成为Spring Cloud第二代标准的实现 在业界广泛使用,已有很多成功案例 Spring Cloud Alibaba真实应用场景 大型复杂的系统,例如大型电商系统 高并发系统,例如大型门户,秒杀系统 需求不明确,且变更很快的系统,例如初创公司业务系统 Sprin

暗余的博客 3万+

RSA算法详解:万字文章详解RSA的加密与解密

为了彻彻底底的研究明白RSA算法,真的是。。煞(lei)费(si)苦(wo)心(le),首先我希望自己前前后后、彻彻底底的琢磨明白,其次我也希望我把他分享出来以后,大家都能读得懂,这篇文章真的是我迄今为止写的又臭又长的一篇文章了,但是我能保证的是,你读完了以后,绝对不会再问RSA是啥玩意儿了。。

布啦啦 7668

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

SpringCloud-Alibaba介绍

SpringCloud-Alibaba介绍 开篇 大家都知道,SpringCloud Alibaba是在SpringCloud基础上开发并开源的一套微服务架构体系。那么,肯定会有小伙伴要问:在微服务领域,SpringCloud已经很火了,为何还要弄出个SpringCloud Alibaba?这不是又要增加我的学习成本吗?今天,我们就来一起聊聊这个话题。 关系 Dubbo与SpringCloud 在之前的微服务架构中,SpringCloud和Dubbo可以说是微服务架构中两种最具代表性的框架(严格意义上来说S

weixin_45203607的博客 2986

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

《SpringCloud Alibaba》实战

文章目录一、 一、 安装启动Nacos 在服务端加依赖

x-dragon8899的博客 2万+

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

SpringCloud Alibaba微服务实战

SpringCloud Alibaba微服务实战系列博客: SpringCloud Alibaba微服务实战一 - 基础环境准备 :http://www.javadaily.cn/articles/2019/11/29/1575026789380.html SpringCloud Alibaba微服务实战二 - 服务注册 :http://www.javadaily.cn/articles/20...

1万+

SpringCloud Alibaba微服务工程搭建(保姆级)

springcloud alibaba 微服务架构,微服务工程搭建

知道的越多 不知道的就越多 2万+

SpringCloud Alibaba 实战,搭建第一个SpringCloud Alibaba项目

搭建AlibabaCloud 首先搭建几个环境全部在Linux下 1、nacos 注册中心 2、sentinel 流量控制,断路 文档 3、apache-skywalking-apm-bin 链路跟踪 4、Rocketmq 的使用 项目下载地址 sentinel JAR下载地址 介绍 NACOS 命名空间的使用 | 创建带有分组的配置、通过配置设置使用的那个分组、然后访问测试显示dev 项目如下 在这里插入代码片 首先创建pom工程 ***Alibaba-Clo.

penggerhe的博客 2万+

SpringCloud Alibaba框架都有啥啊

总结一下SpringCloud Alibaba都集成了哪些组件及各自的作用,希望对SpringCloud Alibaba框架有个全面的认识,后面再根据每个组件深入研究探讨

java后端开发的博客,不仅仅是后端开发 9935

你给我解释解释,为什么TMD非得选择SpringCloud alibaba作为微服务开发框架?

什么是微服务 提到微服务不得不提Martin Fowler在2014年3月25日发表的文章 Microservices,里面给出了微服务的定义。后续国内所有关于微服务的介绍都是基于这篇文章的翻译,或加上自己的理解而成。其中最重要的一段如下: In short, the microservice architectural style [1] is an approach to developing a single application as a suite of small services, eac

飘渺Jam的博客 5502

SpringCloud Alibaba 微服务(一):项目搭建

作为一名开发者,记录学习过程并分享心得是提升自己并帮助他人的有效方式。本文是我学习Spring Cloud Alibaba的第一篇博客,旨在通过记录微服务工程搭建的过程,理解和使用Spring Cloud Alibaba。一、单体应用的痛点难以维护:项目代码量庞大,任何一个小的改动都可能影响整个系统,维护成本高。难以扩展:单体应用难以做到按需扩展,资源利用率低。部署复杂:每次发布都需要将整个应用重新部署,发布周期长且风险大。开发效率低:团队协作开发时,各个模块之间的耦合度高,开发效率受到影响。

分享是一种积极的生活态度~~ 3113

【微服务架构】SpringCloud Alibaba(四):深入讲解 Feign

到这⾥我们基本上可以知道:⽐如当服务B的getById⽅法被调⽤时、会调⽤服务A的getById⽅法,⽽服务A这⾥因为是通过Feign声明式调⽤的,肯定会先通过服务A的Feign动态代理FeignInvocationHandler,从动态代理中的Map<Method, MethodHandler>中、找到具体某个⽅法的SynchronousMethodHandler,然后执⾏该SynchronousMethodHandler中的invoke⽅法来处理⽅法的逻辑。

专注上位机开发、机器视觉、机器学习、嵌入式软硬件开发 1万+

SpringCloud Alibaba 组件介绍

Spring Cloud Alibaba 一、介绍Spring Cloud Alibaba Ⅰ、简介 spring cloud Netflix 相关技术整体进入维护模式 Ribbon、Hystrix、zuul、Eureka、config等 spring cloud 整合Netflix spring cloud alibaba 包含Netflix功能 中文介绍:https://github.com/alibaba/spring-cloud-alibaba/blob/master/README-zh.md

m0_67402125的博客 2万+

SpringCloud Alibaba 详解

SpringCloud Alibaba 基础详解SpringCloud Alibaba 概念SpringCloud Alibaba配置及使用SpringCloud Alibaba Nacos服务注册与发现 SpringCloud Alibaba 概念 1、为什么会出现 SpringCloud Alibaba? SpringCloud Netflix 项目进入了维护模式。意味着 SpringCloud Netflix 将不再开发新的组件。维护中的组件将通过平行组件所替代。 SpringCloud aliba

陌守 2万+
上一篇: 搬砖 1-5年 的 Java 程序员,如何让自己的职业生涯更进一层楼?变得更值钱?
下一篇: 接招吧!最强 “高并发” 系统设计 46 连问,分分钟秒杀一众面试者!
加班不秃顶
博客等级 码龄7年 1822粉丝 599原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值