关于spring-cloud:Spring-Cloud-Gateway-雪崩了我-TM-人傻了

本系列是 我TM人傻了 系列第六期[捂脸],往期精彩回顾: 降级到Spring 5.3.x之后,GC次数急剧减少,我TM人傻了这个大表走索引字段查问的 SQL 怎么就成全扫描了,我TM人傻了获取异样信息里再出异样就找不到日志了,我TM人傻了spring-data-redis 连贯透露,我 TM 人傻了Spring Cloud Gateway 没有链路信息,我 TM 人傻了 大家好,我又人傻了。这次的教训通知咱们,进去写代码偷的懒,迟早要还的。 问题景象与背景昨晚咱们的网关雪崩了一段时间,景象是: 1.一直有各种微服务报异样:在写 HTTP 响应的时候,连贯曾经敞开: reactor.netty.http.client.PrematureCloseException: Connection prematurely closed BEFORE response 2.同时还有申请还没读取完,连贯曾经敞开的异样: org.springframework.http.converter.HttpMessageNotReadableException: I/O error while reading input message; nested exception is java.io.IOException: UT000128: Remote peer closed connection before all data could be read 3.前端一直有申请超时的报警,504 Gateway Time-out 4.网关过程一直健康检查失败而被重启 5.重启后的网关过程,立即申请数量激增,每个实例峰值 2000 qps,闲时每个实例 500 qps,忙时因为有扩容也能放弃每个实例在 1000 qps 以内,而后健康检查接口就很长时间没有响应,导致实例一直重启 其中,1 和 2 的问题应该是应为网关一直重启,并且因为某些起因优雅敞开失败导致强制敞开,强制敞开导致连贯被强制断开从而有 1 和 2 相干的异样。 ...

September 27, 2021 · 4 min · jiezi

关于spring-cloud:Spring-Cloud-Gateway-没有链路信息我-TM-人傻了下

本系列是 我TM人傻了 系列第五期[捂脸],往期精彩回顾: 降级到Spring 5.3.x之后,GC次数急剧减少,我TM人傻了这个大表走索引字段查问的 SQL 怎么就成全扫描了,我TM人傻了获取异样信息里再出异样就找不到日志了,我TM人傻了spring-data-redis 连贯透露,我 TM 人傻了 本篇文章波及底层设计以及原理,以及问题定位和可能的问题点,十分深刻,篇幅较长,所以拆分成上中下三篇: 上:问题简略形容以及 Spring Cloud Gateway 根本构造和流程以及底层原理中:Spring Cloud Sleuth 如何在 Spring Cloud Gateway 退出的链路追踪以及为何会呈现这个问题下:现有 Spring Cloud Sleuth 的非侵入设计带来的性能问题,其余可能的问题点,以及如何解决Spring Cloud Gateway 其余的可能失落链路信息的点通过后面的剖析,咱们能够看出,不止这里,还有其余中央会导致 Spring Cloud Sleuth 的链路追踪信息隐没,这里举几个大家常见的例子: 1.在 GatewayFilter 中指定了异步执行某些工作,因为线程切换了,并且这时候可能 Span 曾经完结了,所以没有链路信息,例如: @Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { return chain.filter(exchange).publishOn(Schedulers.parallel()).doOnSuccess(o -> { //这里就没有链路信息了 log.info("success"); });}2.将 GatewayFilter 中持续链路的 chain.filter(exchange) 放到了异步工作中执行,下面的 AdaptCachedBodyGlobalFilter 就属于这种状况,这样会导致之后的 GatewayFilter 都没有链路信息,例如: @Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { return Mono.delay(Duration.ofSeconds(1)).then(chain.filter(exchange));}Java 并发编程模型与 Project Reactor 编程模型的抵触思考Java 中的很多框架,都用到了 ThreadLocal,或者通过 Thread 来标识唯一性。例如: ...

September 26, 2021 · 3 min · jiezi

关于spring-cloud:Spring-Cloud-Gateway-没有链路信息我-TM-人傻了中

本系列是 我TM人傻了 系列第五期[捂脸],往期精彩回顾: 降级到Spring 5.3.x之后,GC次数急剧减少,我TM人傻了这个大表走索引字段查问的 SQL 怎么就成全扫描了,我TM人傻了获取异样信息里再出异样就找不到日志了,我TM人傻了spring-data-redis 连贯透露,我 TM 人傻了 本篇文章波及底层设计以及原理,以及问题定位和可能的问题点,十分深刻,篇幅较长,所以拆分成上中下三篇: 上:问题简略形容以及 Spring Cloud Gateway 根本构造和流程以及底层原理中:Spring Cloud Sleuth 如何在 Spring Cloud Gateway 退出的链路追踪以及为何会呈现这个问题下:现有 Spring Cloud Sleuth 的非侵入设计带来的性能问题,其余可能的问题点,以及如何解决Spring Cloud Sleuth 是如何减少链路信息通过之前的源码剖析,咱们晓得,在最开始的 TraceWebFilter,咱们将 Mono 封装成了一个 MonoWebFilterTrace,它的外围源码是: @Overridepublic void subscribe(CoreSubscriber<? super Void> subscriber) { Context context = contextWithoutInitialSpan(subscriber.currentContext()); Span span = findOrCreateSpan(context); //将 Span 放入执行上下文中,对于日志其实就是将链路信息放入 org.slf4j.MDC //日志的 MDC 个别都是 ThreadLocal 的 Map,对于 Log4j2 的实现类就是 org.apache.logging.log4j.ThreadContext,其外围 contextMap 就是一个基于 ThreadLocal 实现的 Map //简略了解就是将链路信息放入一个 ThreadLocal 的 Map 中,每个线程拜访本人的 Map 获取链路信息 try (CurrentTraceContext.Scope scope = this.currentTraceContext.maybeScope(span.context())) { //将理论的 subscribe 用 Span 所在的 Context 包裹住,完结时敞开 Span this.source.subscribe(new WebFilterTraceSubscriber(subscriber, context, span, this)); } //在 scope.close() 之后,会将链路信息从 ThreadLocal 的 Map 中剔除}@Overridepublic Object scanUnsafe(Attr key) { if (key == Attr.RUN_STYLE) { //执行的形式必须是不能切换线程,也就是同步的 //因为,日志的链路信息是放在 ThreadLocal 对象中,切换线程,链路信息就没了 return Attr.RunStyle.SYNC; } return super.scanUnsafe(key);}WebFilterTraceSubscriber 干了些什么呢?出现异常,以及 http 申请完结的时候,咱们可能想将响应信息,异样信息记录进入 Span 中,就是通过这个类封装实现的。 ...

September 25, 2021 · 4 min · jiezi

关于spring-cloud:Spring-Cloud-Gateway-没有链路信息我-TM-人傻了上

本系列是 我TM人傻了 系列第五期[捂脸],往期精彩回顾: 降级到Spring 5.3.x之后,GC次数急剧减少,我TM人傻了这个大表走索引字段查问的 SQL 怎么就成全扫描了,我TM人傻了获取异样信息里再出异样就找不到日志了,我TM人傻了spring-data-redis 连贯透露,我 TM 人傻了 本篇文章波及底层设计以及原理,以及问题定位和可能的问题点,十分深刻,篇幅较长,所以拆分成上中下三篇: 上:问题简略形容以及 Spring Cloud Gateway 根本构造和流程以及底层原理中:Spring Cloud Sleuth 如何在 Spring Cloud Gateway 退出的链路追踪以及为何会呈现这个问题下:现有 Spring Cloud Sleuth 的非侵入设计带来的性能问题,其余可能的问题点,以及如何解决咱们的网关应用的是 Spring Cloud Gateway,并且退出了 spring-cloud-sleuth 的依赖,用于链路追踪。并且通过 log4j2 的配置,将链路信息输入到日志中,相干的占位符是: %X{traceId},%X{spanId}然而最近发现,日志中链路信息呈现失落的状况,这是怎么回事呢? Spring Cloud Gateway 的根本流程与实现首先简略介绍一下 Spring Cloud Gateway 的根本构造,以及 Spring Cloud Sleuth 是如何在其中嵌入链路追踪相干代码的。退出 Spring Cloud Sleuth 以及 Prometheus 相干依赖之后, Spring Cloud Gateway 的解决流程如下所示: Spring Cloud Gateway 是基于 Spring WebFlux 开发的异步响应式网关,异步响应式代码比拟难以了解和浏览,我这里给大家分享一种办法去了解,通过这个流程来了解 Spring Cloud Gateway 的工作流程以及底层原理。其实能够了解为,上图这个流程,就是拼出来一个残缺的 Mono(或者 Flux)流,最初 subscribe 执行。 ...

September 24, 2021 · 5 min · jiezi

关于springcloud:第十六篇Docker-安装-CentOS之SpringCloud大型企业分布式微服务云架构源码

Docker 装置 CentOSCentOS(Community Enterprise Operating System)是 Linux 发行版之一,它是来自于 Red Hat Enterprise Linux(RHEL) 按照凋谢源代码规定公布的源代码所编译而成。因为出自同样的源代码,因而有些要求高度稳定性的服务器以 CentOS 代替商业版的 Red Hat Enterprise Linux 应用。举荐分布式架构源码 1、查看可用的 CentOS 版本拜访 CentOS 镜像库地址: 能够通过 Sort by 查看其余版本的 CentOS 。默认是最新版本 centos:latest 。你也能够在下拉列表中找到其余你想要的版本:2、拉取指定版本的 CentOS 镜像,这里咱们装置指定版本为例(centos7): $ docker pull centos:centos73、查看本地镜像应用以下命令来查看是否已装置了 centos7: $ docker images4、运行容器,并且能够通过 exec 命令进入 CentOS 容器。 $ docker run -itd --name centos-test centos:centos75、装置胜利最初咱们能够通过 docker ps 命令查看容器的运行信息:

September 17, 2021 · 1 min · jiezi

关于spring-cloud:14-java-Spring-Cloud企业快速开发架构之Eureka自我保护模式和InstanceID的配置

本节咱们次要介绍 Eureka 自我保护模式的开启和敞开和自定义 Eureka 的 InstanceID 的配置。 举荐分布式架构源码 敞开自我爱护保护模式次要在一组客户端和 Eureka Server 之间存在网络分区场景时应用。一旦进入保护模式,Eureka Server 将会尝试爱护其服务的注册表中的信息,不再删除服务注册表中的数据。当网络故障复原后,该 Eureka Server 节点会主动退出保护模式。 如果在 Eureka 的 Web 控制台看到图 1 所示的内容,就证实 Eureka Server 进入保护模式了。能够通过上面的配置将自我保护模式敞开,这个配置是在 eureka-server 中: eureka.server.enableSelfPreservation=false自定义 Eureka 的 InstanceID客户端在注册时,服务的 Instance ID 的默认值的格局如下: ${spring.cloud.client.hostname}:${spring.application.name}:${spring.application. instance_id:${server.port}}翻译过去就是“主机名:服务名称:服务端口”。当咱们在 Eureka 的 Web 控制台查看服务注册信息的时候,就是这样的一个格局: 1user-PC:eureka-client-user-service:808很多时候咱们想把 IP 显示在上述格局中,此时,只有把主机名替换成 IP 就能够了,或者调整程序也能够。能够改成上面的样子,用“服务名称:服务所在 IP:服务端口”的格局来定义: eureka.instance.instance-id=${spring.application.name}:${spring.cloud.client.ip-address}:${server.port}定义之后咱们看到的就是 eureka-client-user-service:192.168.31.245:8081,一看就晓得是哪个服务,在哪台机器上,端口是多少。 咱们还能够点击服务的 Instance ID 进行跳转,这个时候显示的名称尽管变成了 IP,然而跳转的链接却还是主机名。 所以还须要加一个配置能力让跳转的链接变成咱们想要的样子,应用 IP 进行注册,如图 2 所示: 自定义实例跳转链接刚刚咱们通过配置实现了用 IP 进行注册,当点击 Instance ID 进行跳转的时候,就能够用 IP 跳转了,跳转的地址默认是 IP+Port/info。咱们能够自定义这个跳转的地址: ...

September 17, 2021 · 1 min · jiezi

关于spring-cloud:13-java-Spring-Cloud企业快速开发架构之使用Eureka集群搭建实现高可用服务注册中心

后面咱们搭建的注册核心只适宜本地开发应用,在生产环境中必须搭建一个集群来保障高可用。Eureka 的集群搭建办法很简略:每一台 Eureka 只须要在配置中指定另外多个 Eureka 的地址就能够实现一个集群的搭建了。举荐分布式架构源码 上面咱们以 2 个节点为例来阐明搭建形式。假如咱们有 master 和 slaveone 两台机器,须要做的就是: 将 master 注册到 slaveone 下面。将 slaveone 注册到 master 下面。如果是 3 台机器,以此类推: 将 master 注册到 slaveone 和 slavetwo 下面。将 slaveone 注册到 master 和 slavetwo 下面。将 slavetwo 注册到 master 和 slaveone 下面。搭建步骤创立一个新的我的项目 eureka-server-cluster,配置跟 eureka-server 一样。 首先,咱们须要减少 2 个属性文件,在不同的环境下启动不同的实例。减少 application-master.properties: server.port=8761# 指向你的从节点的Eurekaeureka.client.serviceUrl.defaultZone=http://用户名:明码@localhost:8762/eureka/减少 application-slaveone.properties: server.port=8762# 指向你的主节点的Eurekaeureka.client.serviceUrl.defaultZone=http://用户名:明码 @localhost:8761/eureka/在 application.properties 中增加上面的内容: spring.application.name=eureka-server-cluster# 因为该利用为注册核心, 所以设置为false, 代表不向注册核心注册本人eureka.client.register-with-eureka=false# 因为注册核心的职责就是保护服务实例, 并不需要检索服务, 所以也设置为 falseeureka.client.fetch-registry=falsespring.security.user.name=zhangsanspring.security.user.password=123456# 指定不同的环境spring.profiles.active=master在 A 机器上默认用 master 启动,而后在 B 机器上加上 --spring.profiles.active=slaveone 启动即可。 ...

September 17, 2021 · 1 min · jiezi

关于springcloud:第二十四篇Docker-命令大全之SpringCloud大型企业分布式微服务云架构源码

容器生命周期治理run start/stop/restart kill rm pause/unpause create exec 容器操作ps inspect top attach events logs wait export port 容器rootfs命令commit cp diff 镜像仓库login pull push search 本地镜像治理images rmi tag build history save load import info|versioninfo version 举荐分布式架构源码

September 17, 2021 · 1 min · jiezi

关于spring-cloud:12-java-Spring-Cloud企业快速开发架构之SpringCloudEureka注册中心开启密码认证

Eureka 自带了一个 Web 的治理页面,不便咱们查问注册到下面的实例信息,然而有一个问题:如果在理论应用中,注册核心地址有公网 IP 的话,必然能间接拜访到,这样是不平安的。所以咱们须要对 Eureka 进行革新,加上权限认证来保障安全性。举荐分布式架构源码革新咱们的 eureka-server,通过集成 Spring-Security 来进行平安认证。 在 pom.xml 中增加 Spring-Security 的依赖包,代码如下所示。 <dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-security</artifactId></dependency>而后在 application.properties 中加上认证的配置信息: spring.security.user.name=yinjihuan #用户名spring.security.user.password=123456 #明码减少 Security 配置类: @Configuration@EnableWebSecuritypublic class WebSecurityConfig extends WebSecurityConfigurerAdapter {    @Override    protected void configure(HttpSecurity http) throws Exception {        // 敞开csrf        http.csrf().disable();        // 反对httpBasic        http.authorizeRequests().anyRequest().authenticated().and().httpBasic();    }}重新启动注册核心,拜访 http://localhost:8761/,此时浏览器会提醒你输出用户名和明码,输出正确后能力持续拜访 Eureka 提供的治理页面。 在 Eureka 开启认证后,客户端注册的配置也要加上认证的用户名和明码信息: ...

September 17, 2021 · 1 min · jiezi

关于springcloud:分布式微服务企业快速架构SpringCloud分布式微服务云架构快速开发平台源码

鹄云架构【系统管理平台】是一个大型企业、分布式、微服务、云架构的JavaEE体系疾速研发平台,基于模块化、微服务化、原子化、热部署的设计思维,应用成熟当先的无商业限度的支流开源技术(Spring Cloud+Spring Boot+Mybatis+Oauth2+微服务设计思维)构建。 采纳服务化的组件开发模式,可实现简单的业务性能。应用Maven进行我的项目的构建治理,采纳Jenkins进行继续集成,次要定位于大型分布式企业零碎或大型分布式互联网产品的架构。应用以后最风行最先进的开源技术实现服务组件化及治理,真正为企业打造分布式、微服务、云架构平台。举荐分布式架构源码   【平台安全性】平台严格遵循Web平安标准,应用前后端双重验证,对立用户认证及明码安全策略,规范性能权限、数据权限过滤。应用防SQL脚本注入、跨站点脚本编制(XSS)、伪造申请(CSRF)攻打等常见的攻打伎俩。 业务服务与业务服务提供对外规范Restful接口标准,对内Feign的调用模式,实现分布式集群部署,业务与业务之间齐全解耦,应用Zipkin做服务与服务之间的链路追踪,ES做日志数据收集,真正为企业打造分布式、微服务、云架构平台。 运行环境反对 OPERATING ENVIRONMENT 开发工具:Idea、Eclipse WEB容器:Tomcat、Jboss、Weblogic、webSphere JDK版本:1.8+ 零碎反对:Docker、Window、Linux 数据库/数据源:MySQL、Alibaba Druid 服务框架:Spring Cloud、Spring Boot2、Mybatis、OAuth2、Security 分布式中间件:RabbitMQ、Redis、ElasticSearch、OSS 前端架构:VUE、Uniapp、Layui、Bootstrap、H5、CSS3 构建形式:Maven、Jenkins 波及技术:Eureka、Config、Zuul、OAuth2、Security、OSS、Turbine、Zipkin、Feign、Monitor、Stream、ElasticSearch等 须要框架源码请看我个人简介

September 16, 2021 · 1 min · jiezi

关于spring-cloud:11java-Spring-Cloud企业快速开发架构之使用Eureka编写服务提供者

本节次要解说如何应用 Eureka 编写服务提供者。 1)创立我的项目注册到 Eureka注册核心曾经创立并且启动好了,接下来咱们实现将一个服务提供者 eureka-client-user-service 注册到 Eureka 中,并提供一个接口给其余服务调用。[举荐分布式架构源码](http://minglisoft.cn/hhcloud/)首先还是创立一个 Maven 我的项目,而后在 pom.xml 中减少相干依赖,代码如下所示。 <!-- Spring Boot --><parent>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-parent</artifactId>    <version>2.0.6.RELEASE</version>    <relativePath /></parent><dependencies>    <dependency>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-web</artifactId>    </dependency>    <!-- eureka -->    <dependency>        <groupId>org.springframework.cloud</groupId>        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>    </dependency></dependencies><!-- Spring Cloud --><dependencyManagement>    <dependencies>        <dependency>            <groupId>org.springframework.cloud</groupId>            <artifactId>spring-cloud-dependencies</artifactId>            <version>Finchley.SR2</version>            <type>pom</type>            <scope>import</scope>        </dependency>    </dependencies></dependencyManagement>创立一个启动类 App,代码如下所示。 ...

September 16, 2021 · 1 min · jiezi

关于springcloud:第十三篇Docker-Compose之SpringCloud大型企业分布式微服务云架构源码

Docker ComposeCompose 简介Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您能够应用 YML 文件来配置应用程序须要的所有服务。而后,应用一个命令,就能够从 YML 文件配置中创立并启动所有服务。举荐分布式架构源码 如果你还不理解 YML 文件配置,能够先浏览 。 Compose 应用的三个步骤: 应用 Dockerfile 定义应用程序的环境。 应用 docker-compose.yml 定义形成应用程序的服务,这样它们能够在隔离环境中一起运行。 最初,执行 docker-compose up 命令来启动并运行整个应用程序。 docker-compose.yml 的配置案例如下(配置参数参考下文): 实例# yaml 配置实例version : ' 3'services: web: build : . ports : - "5000:5000" volumes : - .:/code - logvolume01:/var/log links : - redis redis: image : redisvolumes: logvolume01 : { }Compose 装置Linux Linux 上咱们能够从 Github 上下载它的二进制包来应用,最新发行的版本地址: 。 运行以下命令以下载 Docker Compose 的以后稳固版本: ...

September 16, 2021 · 5 min · jiezi

关于spring-cloud:10java-Spring-Cloud企业快速开发架构之SpringCloud使用Eureka编写服务提供者

本节次要解说如何应用 Eureka 编写服务提供者。 1)创立我的项目注册到 Eureka注册核心曾经创立并且启动好了,接下来咱们实现将一个服务提供者 eureka-client-user-service 注册到 Eureka 中,并提供一个接口给其余服务调用。 首先还是创立一个 Maven 我的项目,而后在 pom.xml 中减少相干依赖,代码如下所示。  <!-- Spring Boot --><parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.6.RELEASE</version> <relativePath /></parent><dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- eureka --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency></dependencies><!-- Spring Cloud --><dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Finchley.SR2</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies></dependencyManagement>创立一个启动类 App,代码如下所示。 @SpringBootApplication@EnableDiscoveryClientpublic class App { public static void main(String[] args) { SpringApplication.run(App.class, args); }}启动类的办法与之前没有多大区别,只是注解换成 @EnableDiscoveryClient,示意以后服务是一个 Eureka 的客户端。 接下来在 src/main/resources 上面创立一个 application.properties 属性文件,减少上面的配置: spring.application.name= eureka-client-user-serviceserver.port=8081eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/# 采纳IP注册eureka.instance.preferIpAddress=true# 定义实例ID格局eureka.instance.instance-id=${spring.application.name}:${spring.cloud.client.ip-address}:${server.port}eureka.client.serviceUrl.defaultZone 的地址就是咱们之前启动的 Eureka 服务的地址,在启动的时候须要将本身的信息注册到 Eureka 中去。 ...

September 16, 2021 · 1 min · jiezi

关于spring-cloud:9java-Spring-Cloud企业快速开发架构之SpringCloud搭建Eureka服务注册中心

首先创立一个 Maven 我的项目,取名为 eureka-server,在 pom.xml 中配置 Eureka 的依赖信息,代码如下所示。 须要框架源码请看我个人简介 <!-- Spring Boot --><parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.6.RELEASE</version> <relativePath /></parent><dependencies> <!-- eureka --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency></dependencies><!-- Spring Cloud --><dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Finchley.SR2</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies></dependencyManagement>创立一个启动类 EurekaServerApplication,代码如下所示。 @EnableEurekaServer@SpringBootApplication public static void main(String[] args) { SpringApplication.run(EurekaServer Application.class, args); }}这里所说的启动类,跟咱们之前讲的 Spring Boot 简直齐全一样,只是多了一个 @EnableEurekaServer 注解,示意开启 Eureka Server。 接下来在 src/main/resources 上面创立一个 application.properties 属性文件,减少上面的配置: spring.application.name=eureka-serverserver.port=8761# 因为该利用为注册核心, 所以设置为false, 代表不向注册核心注册本人eureka.client.register-with-eureka=false# 因为注册核心的职责就是保护服务实例, 它并不需要去检索服务, 所以也设置为 falseeureka.client.fetch-registry=false创立一个启动类 EurekaServerApplication,代码如下所示。 ...

September 16, 2021 · 1 min · jiezi

关于spring-cloud:8java-Spring-Cloud企业快速开发架构之SpringCloudSpring-Cloud-Eureka是什么

Spring Cloud Eureka 是 Spring Cloud Netflix 微服务套件的一部分,基于 Netflix Eureka 做了二次封装,次要负责实现微服务架构中的服务治理性能。 Spring Cloud Eureka 是一个基于 REST 的服务,并且提供了基于 Java 的客户端组件,可能十分不便地将服务注册到 Spring Cloud Eureka 中进行对立治理。 服务治理是微服务架构中必不可少的一部分,阿里开源的 Dubbo 框架就是针对服务治理的。服务治理必须要有一个注册核心,除了用 Eureka 作为注册核心外,咱们还能够应用 Consul、Etcd、Zookeeper 等来作为服务的注册核心。 用过 Dubbo 的读者应该分明,Dubbo 中也有几种注册核心,比方基于 Zookeeper、基于 Redis 等,不过用得最多的还是 Zookeeper 形式。 至于应用哪种形式都是能够的,注册核心无非就是治理所有服务的信息和状态。若用咱们生存中的例子来阐明的话,笔者感觉 12306 网站比拟适合。 首先,12306 网站就好比一个注册核心,顾客就好比调用的客户端,当他们须要坐火车时,就会登录 12306 网站上查问余票,有票就能够购买,而后获取火车的车次、工夫等,最初登程。 程序也是一样,当你须要调用某一个服务的时候,你会先去 Eureka 中去拉取服务列表,查看你调用的服务在不在其中,在的话就拿到服务地址、端口等信息,而后调用。 注册核心带来的益处就是,不须要晓得有多少提供方,你只须要关注注册核心即可,就像顾客不用关怀有多少火车在开行,只须要去 12306 网站上看有没有票就能够了。 为什么 Eureka 比 Zookeeper 更适宜作为注册核心呢?次要是因为 Eureka 是基于 AP 准则构建的,而 ZooKeeper 是基于 CP 准则构建的。 在分布式系统畛域有个驰名的 CAP 定理,即 C 为数据一致性;A 为服务可用性;P 为服务对网络分区故障的容错性。这三个个性在任何分布式系统中都不能同时满足,最多同时满足两个。 ...

September 16, 2021 · 1 min · jiezi

关于spring-cloud:7java-Spring-Cloud企业快速开发架构之Spring-Boot-Starter的介绍及使用

Spring Boot 的便利性体现在,它简化了很多繁缛的配置,这对于开发人员来说是一个福音,通过引入各种 Spring Boot Starter 包能够疾速搭建出一个我的项目的脚手架举荐分布式架构源码。 目前提供的 Spring Boot Starter 包有: spring-boot-starter-web:疾速构建基于 Spring MVC 的 Web 我的项目,应用 Tomcat 做默认嵌入式容器。spring-boot-starter-data-redis:操作 Redis。spring-boot-starter-data-mongodb:操作 Mongodb。spring-boot-starter-data-jpa:操作 Mysql。spring-boot-starter-activemq:操作 Activemq。…… 主动配置十分不便,当咱们要操作 Mongodb 的时候,只须要引入 spring-boot-starter-data-mongodb 的依赖,而后配置 Mongodb 的链接信息 spring.data.mongodb.uri=mongodb://localhost/test 就能够应用 MongoTemplate 来操作数据,MongoTemplate 的初始化工作全副交给 Starter 来实现。 主动配置麻烦的是当呈现谬误时,排查问题的难度回升了。主动配置的逻辑都在 Spring Boot Starter 中,要想疾速定位问题,就必须得理解 Spring Boot Starter 的外部原理。接下来咱们本人入手来实现一个 Spring Boot Starter。 Spring Boot Starter我的项目创立创立一个我的项目 spring-boot-starter-demo,pom.xml 配置代码如下所示。 <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency></dependencies>创立一个配置类,用于在属性文件中配置值,相当于 spring.data.mongo 这种模式,代码如下所示。 import org.springframework.boot.context.properties.ConfigurationProperties;import lombok.Data;@Data@ConfigurationProperties("spring.user")public class UserPorperties { private String name;}再定义一个 Client,相当于 MongoTemplate,外面定一个办法,用于获取配置中的值,代码如下所示。 ...

September 15, 2021 · 2 min · jiezi

关于spring-cloud:6java-Spring-Cloud企业快速开发架构之SpringCloudSpring-Boot项目详细搭建步骤

在 Spring Tools 4 for Eclipse 中顺次抉择 File->New->Maven Project,而后在呈现的界面中按图所示减少相干信息。 <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.6.RELEASE</version></parent><dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency></dependencies> 编写启动类,代码如下所示。 @SpringBootApplicationpublic class App { public static void main(String[] args) { SpringApplication.run(App.class, args); }}启动类应用了 @SpringBootApplication 注解,这个注解示意该类是一个 Spring Boot 利用。间接运行 App 类即可启动,启动胜利后在控制台输入信息,默认端口是 8080,如图所示。举荐分布式架构源码 能够看到,咱们只在 pom.xml 中引入了一个 Web 的 Starter,而后创立一个一般的 Java 类,一个 Main 办法就能够启动一个 Web 我的项目。 与之前的应用形式相比,这种形式简略很多。以前须要配置各种 Spring 相干的包,还须要配置 web.xml 文件,还须要将我的项目放入 Tomcat 中去执行,搭建我的项目的过程还特地容易出错,会呈现各种 jar 包抵触。有了 Spring Boot 后这些问题都解决了。 咱们之所以可能通过一个 Main 办法启动一个 Web 服务,是因为 Sprig Boot 中内嵌了 Tomcat,而后通过内嵌的 Tomcat 来提供服务。当然,咱们也能够应用别的容器来替换 Tomcat,比方 Undertow 或 Jetty。 ...

September 15, 2021 · 7 min · jiezi

关于spring-cloud:5java-Spring-Cloud-企业快速开发架构之SpringCloudSpring-Boot简介

Spring Boot 是由 Pivotal 团队提供的全新框架,其设计目标是简化新 Spring 利用的初始搭建以及开发过程。该框架应用了特定的形式进行配置,从而使开发人员不再须要定义样板化的配置。 Spring Boot 致力于在蓬勃发展的疾速利用开发畛域(rapid application development)成为领导者。 在应用 Spring Boot 之前,咱们须要搭建一个我的项目框架并配置各种第三方库的依赖,还须要在 XML 中配置很多内容。 Spring Boot 齐全突破了咱们之前的应用习惯,一分钟就能够创立一个 Web 开发的我的项目;通过 Starter 的形式轻松集成第三方的框架;去掉了 XML 的配置,全副用注解代替。 Spring Boot Starter 是用来简化 jar 包依赖的,集成一个框架只须要引入一个 Starter,而后在属性文件中配置一些值,整个集成的过程就完结了。 不得不说,Spring Boot 在外部做了很多的解决,让开发人员应用起来更加简略了。 上面笔者总结了一些应用 Spring Boot 开发的长处: 基于 Spring 开发 Web 利用更加容易。采纳基于注解形式的配置,防止了编写大量反复的 XML 配置。能够轻松集成 Spring 家族的其余框架,比方 Spring JDBC、Spring Data 等。提供嵌入式服务器,令开发和部署都变得十分不便。  举荐分布式架构源码

September 15, 2021 · 1 min · jiezi

关于spring-cloud:4java-Spring-Cloud企业快速开发架构之SpringCloud-开发环境的准备和Lombok安装步骤

开发环境的筹备次要波及三个方面:JDK、Maven、Spring Tools 4 for Eclipse。 1.JDKJDK 的版本用 1.8 即可,环境变量大家自行去配置。配置好环境变量,在命令行中输出“java -version”可能显示出版本信息即可,如图所示。2.MavenMaven 是用于我的项目构建的,教程所用的版本是 3.6。装置完之后也须要配置环境变量,配置好后同样须要在命令行中输出“mvn -version”进行检测,如图所示。3.Spring Tools 4 for Eclipse大家能够抉择本人相熟的开发工具,不肯定要用 Spring Tools 4 for Eclipse,Spring Tools 4 for Eclipse 下载的地址:http://spring.io/tools。Lombok 装置步骤下载实现后,还须要装置 Lombok 插件,本教程的示例代码会采纳 Lombok 来简化 get,set 办法。 1)官网下载 lombok.jar(https://projectlombok.org/ind...)。 2)间接运行 jar(java -jar lombok.jar 包的绝对路径),如图 3 所示。而后会显示一个界面,如图所示。点击 Install/Update 按钮即可装置胜利,重启 IDE 即可应用。 举荐分布式架构源码

September 15, 2021 · 1 min · jiezi

关于springcloud:分布式微服务企业快速架构SpringCloud分布式微服务云架构快速开发平台源码

鸿鹄云架构【系统管理平台】是一个大型 企业、分布式、微服务、云架构的JavaEE体系疾速研发平台,基于 模块化、微服务化、原子化、热部署的设计思维,应用成熟当先的无商业限度的支流开源技术 (Spring Cloud+Spring Boot+Mybatis+Oauth2+微服务设计思维)构建。 采纳服务化的组件开发模式,可实现简单的业务性能。应用 Maven进行我的项目的构建治理,采纳 Jenkins进行继续集成,次要定位于大型分布式企业零碎或大型分布式互联网产品的架构。应用以后最风行最先进的开源技术实现服务组件化及治理,真正为企业打造 分布式、 微服务、 云架构平台。 【平台安全性】平台严格遵循 Web平安标准,应用 前后端双重验证, 对立用户认证及 明码安全策略,规范 性能权限、数据权限过滤。应用 防SQL脚本注入、 跨站点脚本编制(XSS)、 伪造申请(CSRF)攻打等常见的攻打伎俩。 业务服务与业务服务提供对外规范 Restful接口标准,对内 Feign的调用模式,实现分布式集群部署,业务与业务之间 齐全解耦,应用 Zipkin做服务与服务之间的 链路追踪, ES做日志数据收集,真正为企业打造 分布式、微服务、云架构平台。获取源码

September 14, 2021 · 1 min · jiezi

关于spring-cloud:苦逼的程序员-520-浪漫表白方式

1、按 ctrl+f 而后输出 9996699999966699999966996666996669999666996666999969999999969999999969966669966996699669966669999669999999999999996699666699699666699699666699996666999999999999666669999666996666996996666999966666699999999666666669966669966669969966669999666666669999666666666699666669966996699666699996666666669966666666666996666669999666699999962、除了"好呀",其余都是不好选 3、你的一句今天见,偷走了我整晚的睡眠 4、意见统一的时候听我的,不同的时候听女朋友的 5、山无陵, 江水为竭, 冬雷震震, 夏雨雪, 天地合, 乃敢与君绝! 6、春风十里不如你 7、直到死之前,每天爱你多一点 8、没有你,我就没方法对世界说"你好" 9、如果你觉的我是一个乏味的人,我想那是最好不过的了 10、当然,有时候也有意外状况 详情看我个人简介

September 14, 2021 · 1 min · jiezi

关于spring-cloud:J2EE分布式微服务云开发架构-Spring-CloudMybatisElementUI-前后端分离

鸿鹄云架构【系统管理平台】是一个大型企业、分布式、微服务、云架构的JavaEE体系疾速研发平台,基于模块化、微服务化、原子化、热部署的设计思维,应用成熟当先的无商业限度的支流开源技术(Spring Cloud+Spring Boot+Mybatis+Oauth2+微服务设计思维)构建。 采纳服务化的组件开发模式,可实现简单的业务性能。应用Maven进行我的项目的构建治理,采纳Jenkins进行继续集成,次要定位于大型分布式企业零碎或大型分布式互联网产品的架构。应用以后最风行最先进的开源技术实现服务组件化及治理,真正为企业打造分布式、微服务、云架构平台。 【平台安全性】平台严格遵循Web平安标准,应用前后端双重验证,对立用户认证及明码安全策略,规范性能权限、数据权限过滤。应用防SQL脚本注入、跨站点脚本编制(XSS)、伪造申请(CSRF)攻打等常见的攻打伎俩。 业务服务与业务服务提供对外规范Restful接口标准,对内Feign的调用模式,实现分布式集群部署,业务与业务之间齐全解耦,应用Zipkin做服务与服务之间的链路追踪,ES做日志数据收集,真正为企业打造分布式、微服务、云架构平台。原码起源

September 14, 2021 · 1 min · jiezi

关于spring-cloud:第六篇云服务器之Spring-Cloud直播商城-b2b2c电子商务技术总结

云服务器云服务器(Elastic Compute Service, ECS)是一种简略高效、安全可靠、解决能力可弹性伸缩的计算服务。 云服务器治理形式比物理服务器更简略高效,咱们无需提前购买低廉的硬件,即可迅速创立或删除云服务器,云服务器费用个别在几十到几百不等,能够依据咱们的需要配置。 目前市场上的云服务器很多,这里次要介绍以下几家: :流动折扣力度很大(1核2G,72.60/年)。 :腾讯云目前流动多一些,性价比也高。 留神:很多云服务器给新用户提供的优惠力度是最大,基本上都是 1~2 折,倡议新注册的用户购买。阿里云新用户购买具体信息,能够点击上面的图片。阿里流动, 不分新老用户,能够领红包参加满减流动,续费也有专门的优惠券,续费优惠券。 留神:阿里云 突发性能型的服务器真的只能本人学习用,如果要用对外提供服务要谨慎抉择,因为它性能瓶颈限度很大,不过价格便宜就是了。当然,你也能够间接到 抉择更多配置及其他地区的云服务器:红框为无需备案地区:腾讯云腾讯云秒杀流动已开始,以下几款性价比十分高,有几款是须要抢购的,大家看好工夫根本能拿到。 1、 1核2G 74/年、219元/3年( 原价:1506/年),能够用来学习,Linux 常识对技术人员的成才十分重要。2、 2核4G 3M 带宽 1 年 328( 原价:3198元)。3、如果须要购买海内服务器(国内要备案),能够点击: https://curl.qcloud.com/5C1FtZ3S。每个工夫点都有不同的配置跟价格,具体信息,能够点击上面的图片( https://curl.qcloud.com/JsztA7Wh)。国内服务器如果要做网站之类的还得备案,中国香港地区和海内的是不须要备案的,能够点击: https://curl.qcloud.com/5C1FtZ3S 链接,抉择不同区域购买,以下红框局部不须要备案。腾讯云服务器应用本章节以腾讯云服务器为例。 1、首先点击下图购买(更多服务器的配置信息见下文):2、登陆腾讯云控制台,查看已购买的服务器:3、在应用腾讯云服务器前,咱们须要先创立一个 SSH 密钥,点击左侧的 SSH 密钥 (应用密钥登录比明码更平安):输出密钥名称,而后点击确定,就会主动生成一个密钥,密钥会主动下载到本地,请保留好下载的密钥,密钥文件名就是你输出的密钥名称。 4、接着咱们勾选曾经创立的密钥,点击 绑定/解绑实例 按钮,弹窗中会呈现咱们的 ECS 服务器,将其绑定到这个密钥即可:5、返回实例列表,点击实例右侧的 登录 按钮,弹窗中点击立刻登录,这是会弹出一个新的浏览器窗口,咱们抉择密钥登录,密钥文件就是在第三个步骤创立的:当然你能够抉择第三方客户端登录(如:SecureCRT),用户名为 ubuntu,其余零碎预计略有不同,而后导入对应的 key 即可。

September 13, 2021 · 1 min · jiezi

关于spring-cloud:第三篇CentOS-Docker-安装之Spring-Cloud直播商城-b2b2c电子商务技术总结

CentOS Docker 装置Docker 反对以下的 64 位 CentOS 版本: CentOS 7CentOS 8更高版本...应用官网装置脚本主动装置装置命令如下: > curl -fsSL | bash -s docker --mirror Aliyun也能够应用国内 daocloud 一键装置命令: curl -sSL | sh卸载旧版本较旧的 Docker 版本称为 docker 或 docker-engine 。如果已装置这些程序,请卸载它们以及相干的依赖项。 $ sudo yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine装置 Docker Engine-Community应用 Docker 仓库进行装置在新主机上首次装置 Docker Engine-Community 之前,须要设置 Docker 仓库。之后,您能够从仓库装置和更新 Docker。 设置仓库 装置所需的软件包。yum-utils 提供了 yum-config-manager ,并且 device mapper 存储驱动程序须要 device-mapper-persistent-data 和 lvm2。 ...

September 13, 2021 · 1 min · jiezi

关于spring-cloud:第四篇Git-工作区暂存区和版本库之Spring-Cloud直播商城-b2b2c电子商务技术总结

基本概念咱们先来了解下 Git 工作区、暂存区和版本库概念: 工作区:就是你在电脑里能看到的目录。暂存区:英文叫 stage 或 index。个别寄存在 .git 目录下的 index 文件(.git/index)中,所以咱们把暂存区有时也叫作索引(index)。版本库:工作区有一个暗藏目录 .git,这个不算工作区,而是 Git 的版本库。上面这个图展现了工作区、版本库中的暂存区和版本库之间的关系:图中左侧为工作区,右侧为版本库。在版本库中标记为 "index" 的区域是暂存区(stage/index),标记为 "master" 的是 master 分支所代表的目录树。 图中咱们能够看出此时 "HEAD" 理论是指向 master 分支的一个"游标"。所以图示的命令中呈现 HEAD 的中央能够用 master 来替换。 图中的 objects 标识的区域为 Git 的对象库,理论位于 ".git/objects" 目录下,外面蕴含了创立的各种对象及内容。 当对工作区批改(或新增)的文件执行 git add 命令时,暂存区的目录树被更新,同时工作区批改(或新增)的文件内容被写入到对象库中的一个新的对象中,而该对象的ID被记录在暂存区的文件索引中。 当执行提交操作(git commit)时,暂存区的目录树写到版本库(对象库)中,master 分支会做相应的更新。即 master 指向的目录树就是提交时暂存区的目录树。 当执行 git reset HEAD 命令时,暂存区的目录树会被重写,被 master 分支指向的目录树所替换,然而工作区不受影响。 当执行 git rm --cached <file> 命令时,会间接从暂存区删除文件,工作区则不做出扭转。 当执行 git checkout . 或者 git checkout -- <file> 命令时,会用暂存区全副或指定的文件替换工作区的文件。这个操作很危险,会革除工作区中未增加到暂存区中的改变。 当执行 git checkout HEAD . 或者 git checkout HEAD <file> 命令时,会用 HEAD 指向的 master 分支中的全副或者局部文件替换暂存区和以及工作区中的文件。这个命令也是极具危险性的,因为岂但会革除工作区中未提交的改变,也会革除暂存区中未提交的改变。 ...

September 8, 2021 · 1 min · jiezi

关于spring-cloud:第十六篇-Maven-自动化部署之Spring-Cloud直播商城-b2b2c电子商务技术总结

Maven 自动化部署我的项目开发过程中,部署的过程蕴含需如下步骤: 将所的我的项目代码提交到 SVN 或者代码库中并打上标签。从 SVN 上下载残缺的源代码。构建利用。存储构建输入的 WAR 或者 EAR 文件到一个罕用的网络地位下。从网络上获取文件并且部署文件到生产站点上。更新文档并且更新利用的版本号。问题形容通常状况下下面的提到开发过程中会波及到多个团队。一个团队可能负责提交代码,另一个团队负责构建等等。很有可能因为波及的人为操作和多团队环境的起因,任何一个步骤都可能出错。比方,较旧的版本没有在网络机器上更新,而后部署团队又重新部署了较早的构建版本。 解决方案通过联合以下计划来实现自动化部署: 应用 Maven 构建和公布我的项目应用 SubVersion, 源码仓库来治理源代码应用近程仓库管理软件(Jfrog或者Nexus) 来治理我的项目二进制文件。批改我的项目的 pom.xml咱们将会应用 Maven 公布的插件来创立一个自动化公布过程。 例如,bus-core-api 我的项目的 pom.xml 文件代码如下: <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> <groupId>bus-core-api</groupId> <artifactId>bus-core-api</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <scm> <url>http://www.svn.com</url> <connection>scm:svn:http://localhost:8080/svn/jrepo/trunk/ Framework</connection> <developerConnection>scm:svn:${username}/${password}@localhost:8080: common_core_api:1101:code</developerConnection> </scm> <distributionManagement> <repository> <id>Core-API-Java-Release</id> <name>Release repository</name> <url>http://localhost:8081/nexus/content/repositories/ Core-Api-Release</url> </repository> </distributionManagement> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-release-plugin</artifactId> <version>2.0-beta-9</version> <configuration> <useReleaseProfile>false</useReleaseProfile> <goals>deploy</goals> <scmCommentPrefix>[bus-core-api-release-checkin]-< /scmCommentPrefix> </configuration> </plugin> </plugins> </build></project>在 pom.xml 文件中,咱们罕用到的一些重要元素节点如下表所示:Maven Release 插件Maven 应用 maven-release-plugin 插件来实现以下工作。mvn release:clean清理工作空间,保障最新的公布过程胜利进行。mvn release:rollback在上次公布过程不胜利的状况下,回滚批改的工作空间代码和配置保障公布过程胜利进行。 ...

September 8, 2021 · 1 min · jiezi

关于spring-cloud:第十五篇-Maven-依赖管理之Spring-Cloud直播商城-b2b2c电子商务技术总结

Maven 依赖治理Maven 一个外围的个性就是依赖治理。当咱们解决多模块的我的项目(蕴含成千盈百个模块或者子项目),模块间的依赖关系就变得非常复杂,治理也变得很艰难。针对此种情景,Maven 提供了一种高度管制的办法。 可传递性依赖发现一种相当常见的状况,比如说 A 依赖于其余库 B。如果,另外一个我的项目 C 想要应用 A ,那么 C 我的项目也须要应用库 B。 Maven 能够防止去搜寻所有所需库的需要。Maven 通过读取我的项目文件(pom.xml),找出它们我的项目之间的依赖关系。 咱们须要做的只是在每个我的项目的 pom 中定义好间接的依赖关系。其余的事件 Maven 会帮咱们搞定。 通过可传递性的依赖,所有被蕴含的库的图形会疾速的增长。当有反复库时,可能呈现的情景将会持续上升。Maven 提供一些性能来管制可传递的依赖的水平。依赖范畴传递依赖发现能够通过应用如下的依赖范畴来失去限度:依赖治理通常状况下,在一个共通的我的项目下,有一系列的我的项目。在这种状况下,咱们能够创立一个公共依赖的 pom 文件,该 pom 蕴含所有的公共的依赖关系,咱们称其为其余子项目 pom 的 pom 父。 接下来的一个例子能够帮忙你更好的了解这个概念。 接下来是下面依赖图的详情阐明: App-UI-WAR 依赖于 App-Core-lib 和 App-Data-lib。 Root 是 App-Core-lib 和 App-Data-lib 的父我的项目。 Root 在它的依赖局部定义了 Lib1、lib2 和 Lib3 作为依赖。 App-UI-WAR 的 pom.xml 文件代码如下: <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> <groupId>com.companyname.groupname</groupId> <artifactId>App-UI-WAR</artifactId> <version>1.0</version> <packaging>war</packaging> <dependencies> <dependency> <groupId>com.companyname.groupname</groupId> <artifactId>App-Core-lib</artifactId> <version>1.0</version> </dependency> </dependencies> <dependencies> <dependency> <groupId>com.companyname.groupname</groupId> <artifactId>App-Data-lib</artifactId> <version>1.0</version> </dependency> </dependencies> </project>App-Core-lib 的 pom.xml 文件代码如下: ...

September 8, 2021 · 1 min · jiezi

关于spring-cloud:第十四篇-Maven-自动化构建之Spring-Cloud直播商城-b2b2c电子商务技术总结

Maven 自动化构建自动化构建定义了这样一种场景: 在一个我的项目胜利构建实现后,其相干的依赖工程即开始构建,这样能够保障其依赖我的项目的稳固。 比方一个团队正在开发一个我的项目 bus-core-api, 并且有其余两个我的项目 app-web-ui 和 app-desktop-ui 依赖于这个我的项目。 app-web-ui 我的项目应用的是 bus-core-api 我的项目的 1.0 快照: <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> <groupId>app-web-ui</groupId> <artifactId>app-web-ui</artifactId> <version>1.0</version> <packaging>jar</packaging> <dependencies> <dependency> <groupId>bus-core-api</groupId> <artifactId>bus-core-api</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies></project>app-desktop-ui 我的项目应用的是 bus-core-api 我的项目的 1.0 快照: <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> <groupId>app-desktop-ui</groupId> <artifactId>app-desktop-ui</artifactId> <version>1.0</version> <packaging>jar</packaging> <dependencies> <dependency> <groupId>bus-core-api</groupId> <artifactId>bus-core-api</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies></project>bus-core-api 我的项目: <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> <groupId>bus-core-api</groupId> <artifactId>bus-core-api</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> </project>当初 app-web-ui 和 app-desktop-ui 我的项目的团队要求不论 bus-core-api 我的项目何时变动,他们的构建过程都该当能够启动。 ...

September 7, 2021 · 2 min · jiezi

关于spring-cloud:第五篇Maven-构建配置文件之Spring-Cloud直播商城-b2b2c电子商务技术总结

Maven 构建配置文件构建配置文件是一系列的配置项的值,能够用来设置或者笼罩 Maven 构建默认值。 应用构建配置文件,你能够为不同的环境,比如说生产环境(Production)和开发(Development)环境,定制构建形式。 配置文件在 pom.xml 文件中应用 activeProfiles 或者 profiles 元素指定,并且能够通过各种形式触发。配置文件在构建时批改 POM,并且用来给参数设定不同的指标环境(比如说,开发(Development)、测试(Testing)和生产环境(Production)中数据库服务器的地址)。 构建配置文件的类型构建配置文件大体上有三种类型:配置文件激活Maven的构建配置文件能够通过多种形式激活。 应用命令控制台输出显式激活。通过 maven 设置。基于环境变量(用户或者零碎变量)。操作系统设置(比如说,Windows系列)。文件的存在或者缺失。配置文件激活实例假设我的项目构造如下:其中在src/main/resources文件夹下有三个用于测试文件:留神:这三个配置文件并不是代表构建配置文件的性能,而是用于本次测试的目标;比方,我指定了构建配置文件为 prod 时,我的项目就应用 env.prod.properties文件。 留神:上面的例子依然是应用 AntRun 插件,因为此插件能绑定 Maven 生命周期阶段,并通过 Ant 的标签不必编写一点代码即可输入信息、复制文件等,经此而已。其余的与本次构建配置文件无关。 1、配置文件激活profile 能够让咱们定义一系列的配置信息,而后指定其激活条件。这样咱们就能够定义多个 profile,而后每个 profile 对应不同的激活条件和配置信息,从而达到不同环境应用不同配置信息的成果。 以下实例,咱们将 maven-antrun-plugin:run 指标增加到测试阶段中。这样咱们能够在不同的 profile 中输入文本信息。咱们将应用 pom.xml 来定义不同的 profile,并在命令控制台中应用 maven 命令激活 profile。 pom.xml 文件如下: <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/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.jsoft.test</groupId> <artifactId>testproject</artifactId> <packaging>jar</packaging> <version>0.1-SNAPSHOT</version> <name>testproject</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> </dependencies> <profiles> <profile> <id>test</id> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-antrun-plugin</artifactId> <version>1.8</version> <executions> <execution> <phase>test</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <echo>Using env.test.properties</echo> <copy file="src/main/resources/env.test.properties" tofile="${project.build.outputDirectory}/env.properties" overwrite="true"/> </tasks> </configuration> </execution> </executions> </plugin> </plugins> </build> </profile> <profile> <id>normal</id> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-antrun-plugin</artifactId> <version>1.8</version> <executions> <execution> <phase>test</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <echo>Using env.properties</echo> <copy file="src/main/resources/env.properties" tofile="${project.build.outputDirectory}/env.properties" overwrite="true"/> </tasks> </configuration> </execution> </executions> </plugin> </plugins> </build> </profile> <profile> <id>prod</id> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-antrun-plugin</artifactId> <version>1.8</version> <executions> <execution> <phase>test</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <echo>Using env.prod.properties</echo> <copy file="src/main/resources/env.prod.properties" tofile="${project.build.outputDirectory}/env.properties" overwrite="true"/> </tasks> </configuration> </execution> </executions> </plugin> </plugins> </build> </profile> </profiles></project>留神:构建配置文件采纳的是 <profiles> 节点。 ...

September 7, 2021 · 3 min · jiezi

关于spring-cloud:SpringCloud升级之路20200x版24测试Spring-Cloud-LoadBalancer

本系列代码地址:https://github.com/HashZhang/...通过单元测试,咱们也能够理解下个别咱们实现 spring cloud 自定义的根底组件,怎么去单元测试。 这里的单元测试次要测试三个场景: 只返回同一个 zone 下的实例,其余 zone 的不会返回对于多个申请,每个申请返回的与上次的实例不同。对于多线程的每个申请,如果重试,返回的都是不同的实例同时,咱们也须要针对同步和异步两个配置,别离进行测试,同步和异步两种配置测试逻辑是一样的,只是测试的 Bean 不一样: 同步环境是 DiscoveryClient,异步环境是 ReactiveDiscoveryClient同步环境负载均衡器是 LoadBalancer,异步环境负载均衡器是 ReactiveLoadBalancer同步测试代码请参考:LoadBalancerTest.java,异步测试代码请参考:LoadBalancerTest.java 咱们这里应用同步测试代码作为例子展现: //SpringExtension也蕴含了MockitoJUnitRunner,所以 @Mock 等注解也失效了@ExtendWith(SpringExtension.class)@SpringBootTest(properties = {LoadBalancerEurekaAutoConfiguration.LOADBALANCER_ZONE + "=zone1"})public class LoadBalancerTest { @EnableAutoConfiguration @Configuration public static class App { @Bean public DiscoveryClient myDiscoveryClient() { ServiceInstance zone1Instance1 = Mockito.spy(ServiceInstance.class); ServiceInstance zone1Instance2 = Mockito.spy(ServiceInstance.class); ServiceInstance zone2Instance3 = Mockito.spy(ServiceInstance.class); Map<String, String> zone1 = Map.ofEntries( Map.entry("zone", "zone1") ); Map<String, String> zone2 = Map.ofEntries( Map.entry("zone", "zone2") ); when(zone1Instance1.getMetadata()).thenReturn(zone1); when(zone1Instance1.getInstanceId()).thenReturn("instance1"); when(zone1Instance2.getMetadata()).thenReturn(zone1); when(zone1Instance2.getInstanceId()).thenReturn("instance2"); when(zone2Instance3.getMetadata()).thenReturn(zone2); when(zone2Instance3.getInstanceId()).thenReturn("instance3"); DiscoveryClient spy = Mockito.spy(DiscoveryClient.class); Mockito.when(spy.getInstances("testService")) .thenReturn(List.of(zone1Instance1, zone1Instance2, zone2Instance3)); return spy; } } @SpyBean private LoadBalancerClientFactory loadBalancerClientFactory; @SpyBean private Tracer tracer; /** * 只返回同一个 zone 下的实例 */ @Test public void testFilteredByZone() { ReactiveLoadBalancer<ServiceInstance> testService = loadBalancerClientFactory.getInstance("testService"); for (int i = 0; i < 100; i++) { ServiceInstance server = Mono.from(testService.choose()).block().getServer(); //必须处于和以后实例同一个zone下 Assertions.assertEquals(server.getMetadata().get("zone"), "zone1"); } } /** * 返回不同的实例 */ @Test public void testReturnNext() { ReactiveLoadBalancer<ServiceInstance> testService = loadBalancerClientFactory.getInstance("testService"); Span span = tracer.nextSpan(); for (int i = 0; i < 100; i++) { try (Tracer.SpanInScope cleared = tracer.withSpanInScope(span)) { ServiceInstance server1 = Mono.from(testService.choose()).block().getServer(); ServiceInstance server2 = Mono.from(testService.choose()).block().getServer(); //每次抉择的是不同实例 Assertions.assertNotEquals(server1.getInstanceId(), server2.getInstanceId()); } } } /** * 跨线程,默认状况下是可能返回同一实例的,在咱们的实现下,放弃 * span 则会返回下一个实例,这样保障多线程环境同一个 request 重试会返回下一实例 * * @throws Exception */ @Test public void testSameSpanReturnNext() throws Exception { Span span = tracer.nextSpan(); for (int i = 0; i < 100; i++) { try (Tracer.SpanInScope cleared = tracer.withSpanInScope(span)) { ReactiveLoadBalancer<ServiceInstance> testService = loadBalancerClientFactory.getInstance("testService"); ServiceInstance server1 = Mono.from(testService.choose()).block().getServer(); AtomicReference<ServiceInstance> server2 = new AtomicReference<>(); Thread thread = new Thread(() -> { try (Tracer.SpanInScope cleared2 = tracer.withSpanInScope(span)) { server2.set(Mono.from(testService.choose()).block().getServer()); } }); thread.start(); thread.join(); System.out.println(i); Assertions.assertNotEquals(server1.getInstanceId(), server2.get().getInstanceId()); } } }}运行测试,测试通过。 ...

August 29, 2021 · 2 min · jiezi

关于spring-cloud:SpringCloud升级之路20200x版23订制Spring-Cloud-LoadBalancer

本系列代码地址:https://github.com/HashZhang/...咱们应用 Spring Cloud 官网举荐的 Spring Cloud LoadBalancer 作为咱们的客户端负载均衡器。上一节咱们理解了 Spring Cloud LoadBalancer 的构造,接下来咱们来说一下咱们在应用 Spring Cloud LoadBalancer 要实现的性能: 咱们要实现不同集群之间不相互调用,通过实例的metamap中的zone配置,来辨别不同集群的实例。只有实例的metamap中的zone配置一样的实例能力相互调用。这个通过实现自定义的 ServiceInstanceListSupplier 即可实现负载平衡的轮询算法,须要申请与申请之间隔离,不能共用同一个 position 导致某个申请失败之后的重试还是原来失败的实例。上一节看到的默认的 RoundRobinLoadBalancer 是所有线程共用同一个原子变量 position 每次申请原子加 1。在这种状况下会有问题:假如有微服务 A 有两个实例:实例 1 和实例 2。申请 A 达到时,RoundRobinLoadBalancer 返回实例 1,这时有申请 B 达到,RoundRobinLoadBalancer 返回实例 2。而后如果申请 A 失败重试,RoundRobinLoadBalancer 又返回了实例 1。这不是咱们冀望看到的。针对这两个性能,咱们别离编写本人的实现。 Spring Cloud LoadBalancer 中的 zone 配置Spring Cloud LoadBalancer 定义了 LoadBalancerZoneConfig: public class LoadBalancerZoneConfig { //标识以后负载均衡器处于哪一个 zone private String zone; public LoadBalancerZoneConfig(String zone) { this.zone = zone; } public String getZone() { return zone; } public void setZone(String zone) { this.zone = zone; }}如果没有引入 Eureka 相干依赖,则这个 zone 通过 spring.cloud.loadbalancer.zone 配置:LoadBalancerAutoConfiguration ...

August 28, 2021 · 4 min · jiezi

关于spring-cloud:SpringCloud升级之路20200x版22Spring-Cloud-LoadBalancer核心源码

本系列代码地址:https://github.com/HashZhang/...通过上一节的详细分析,咱们晓得能够通过 LoadBalancerClientFactory 晓得默认配置类为 LoadBalancerClientConfiguration. 并且获取微服务名称能够通过 environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME); [LoadBalancerClientFactory]() public static final String NAMESPACE = "loadbalancer";public static final String PROPERTY_NAME = NAMESPACE + ".client.name";public LoadBalancerClientFactory() { super(LoadBalancerClientConfiguration.class, NAMESPACE, PROPERTY_NAME);}查看配置类 LoadBalancerClientConfiguration,咱们能够发现这个类次要定义两种 Bean,别离是 ReactorLoadBalancer<ServiceInstance> 和 ServiceInstanceListSupplier。 ReactorLoadBalancer 是负载均衡器,次要提供依据服务名称获取服务实例列表并从从中抉择的性能。 [ReactorLoadBalancer]() Mono<Response<T>> choose(Request request);在默认配置中的实现是: [LoadBalancerClientConfiguration]() @Bean@ConditionalOnMissingBeanpublic ReactorLoadBalancer<ServiceInstance> reactorServiceInstanceLoadBalancer( Environment environment, LoadBalancerClientFactory loadBalancerClientFactory) { //获取微服务名称 String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME); //创立 RoundRobinLoadBalancer //留神这里注入的是 LazyProvider,这次要因为在注册这个 Bean 的时候相干的 Bean 可能还没有被加载注册,利用 LazyProvider 而不是间接注入所需的 Bean 避免报找不到 Bean 注入的谬误。 return new RoundRobinLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);}能够看出,默认配置的 ReactorLoadBalancer 实现是 RoundRobinLoadBalancer。这个负载均衡器实现很简略,有一个原子类型的 AtomicInteger position,从 ServiceInstanceListSupplier 中读取所有的服务实例列表,而后对于 position 原子加1,对列表大小取模,返回列表中这个地位的服务实例 ServiceInstance。 ...

August 27, 2021 · 3 min · jiezi

关于spring-cloud:SpringCloud升级之路20200x版21Spring-Cloud-LoadBalancer简介

本系列代码地址:https://github.com/HashZhang/...咱们应用 Spring Cloud 官网举荐的 Spring Cloud LoadBalancer 作为咱们的客户端负载均衡器。 Spring Cloud LoadBalancer背景Spring Cloud LoadBalancer是一个客户端负载均衡器,相似于Ribbon,然而因为Ribbon曾经进入保护模式,并且Ribbon 2并不与Ribbon 1互相兼容,所以Spring Cloud全家桶在Spring Cloud Commons我的项目中,增加了Spring cloud Loadbalancer作为新的负载均衡器,并且做了向前兼容,就算你的我的项目中持续用 Spring Cloud Netflix 套装(包含Ribbon,Eureka,Zuul,Hystrix等等)让你的我的项目中有这些依赖,你也能够通过简略的配置,把ribbon替换成Spring Cloud LoadBalancer。 负载均衡器在哪里应用?Spring Cloud 中外部微服务调用默认是 http 申请,次要通过上面三种 API: RestTemplate:同步 http APIWebClient:异步响应式 http API三方客户端封装,例如 openfeign如果我的项目中退出了 spring-cloud-loadbalancer 的依赖并且配置启用了,那么会主动在相干的 Bean 中退出负载均衡器的个性。 对于 RestTemplate,会主动对所有 @LoadBalanced 注解润饰的 RestTemplate Bean 减少 Interceptor 从而加上了负载均衡器的个性。对于 WebClient,会主动创立 ReactorLoadBalancerExchangeFilterFunction,咱们能够通过退出ReactorLoadBalancerExchangeFilterFunction会退出负载均衡器的个性。对于三方客户端,个别不须要咱们额定配置什么。这些应用的示例,会在咱们系列降级完最初的测试局部看到。 Spring Cloud LoadBalancer 构造简介系列之前的文章咱们提到了 NamedContextFactory,Spring Cloud LoadBalancer 这里也是应用了这个机制实现了不同微服务应用不同的 Spring Cloud LoadBalancer 配置。相干外围实现是 @LoadBalancerClient 和 @LoadBalancerClients 这两个注解,以及 NamedContextFactory.Specification 的实现 LoadBalancerClientSpecification,NamedContextFactory 的实现 LoadBalancerClientFactory。如下图所示: ...

August 26, 2021 · 1 min · jiezi

关于spring-cloud:SpringCloud升级之路20200x版20-启动一个-Eureka-Server-集群

本系列代码地址:https://github.com/HashZhang/... 咱们的业务集群构造是这样的: 不同 Region,应用不同的 Eureka 集群治理,不同 Region 之间不相互拜访。同一 Region 内,可能有不同的业务集群,不同业务集群之间也不相互拜访,共用同一套业务集群。同一业务集群内能够随便拜访,同时同一业务集群会做跨可用区的容灾。在咱们这里的形象中,zone 代表不同集群,而不是理论的不同可用区。 在这里,咱们提供一个 Eureka Server 的集群模板,供大家参考。 首先,我的项目依赖是: <dependencies> <dependency> <groupId>com.github.hashjang</groupId> <artifactId>spring-cloud-iiford-spring-cloud-webmvc</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency></dependencies>其实就是蕴含之前咱们定义的所有同步微服务的依赖,以及 eureka-server 的相干依赖。 编写启动类,其实外围就是增加注解 @EnableEurekaServer package com.github.hashjang.spring.cloud.iiford.eureka.server;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;@SpringBootApplication@EnableEurekaServerpublic class EurekaServerApplication { public static void main(String[] args) { SpringApplication.run(EurekaServerApplication.class, args); }}咱们筹备启动一个两个 Eureka Server 实例的集群,首先编写两个实例公共的配置,放入 application.yml: spring: application: name: eureka-servereureka: server: #被动查看服务实例是否生效的工作执行距离,默认是 60s eviction-interval-timer-in-ms: 1000 #这个配置在两个中央被应用: #如果启用用了自我爱护,则会 renewal-threshold-update-interval-ms 指定的工夫内,收到的心跳申请个数是否小于实例个数乘以这个 renewal-percent-threshold #定时工作查看过期实例,每次最多过期 1 - renewal-percent-threshold 这么多比例的实例 renewal-percent-threshold: 0.85 #留神,最好所有的客户端实例配置的心跳工夫相干的配置,是雷同的。这样应用自我爱护的个性最精确。 #敞开自我爱护 #咱们这里不应用自我爱护,因为: #自我爱护次要针对集群中网络呈现问题,导致有很多实例无奈发送心跳导致很多实例状态异样,然而理论实例还在失常工作的状况,不要让这些实例不参加负载平衡 #启用自我爱护的状况下,就会进行对于实例的过期 #然而,如果呈现这种状况,其实也代表很多实例无奈读取注册核心了。 #并且还有一种状况就是,Eureka 重启。尽管不常见,然而对于镜像中其余的组件更新咱们还是很频繁的 #我偏向于从客户端对于实例缓存机制来解决这个问题,如果返回实例列表为空,则应用上次的实例列表进行负载平衡,这样既能解决 Eureka 重启的状况,又能解决一些 Eureka 网络隔离的状况 #自我保护模式基于每分钟须要收到 renew (实例心跳)申请个数,如果启用了自我保护模式,只有上一分钟接管到的 renew 个数,大于这个值,实例过期才会被登记 enable-self-preservation: false # 增量实例队列实例过期工夫,默认 3 分钟 retention-time-in-m-s-in-delta-queue: 180000 # 增量实例队列过期工作距离,默认 30s delta-retention-timer-interval-in-ms: 30000 # 响应缓存中有两个次要元素,一个是 readOnlyCacheMap,另一个是 readWriteCacheMap # 是否应用 readOnlyCacheMap,默认为 true # 如果为是,则从 readOnlyCacheMap 读取,否则间接读取 readWriteCacheMap use-readonly-response-cahce: true # 初始 readWriteCacheMap 大小,默认 1000 initial-capacity-of-response-cache: 1000 # LoadingCache 缓存过期工夫,默认 180s response-cache-auto-expiration-in-seconds: 9 # 定时从 LoadingCache 同步到只读缓存的间隔时间,默认为 30s response-cache-update-interval-ms: 3000 client: service-url: # 默认eureka集群,这里必须是defaultZone,不能用-替换大写,与其余的配置不一样,因为切实EurekaClientConfigBean外面写死的 defaultZone: 'http://127.0.0.1:8211/eureka/,http://127.0.0.1:8212/eureka/' # 是否从 eureka 下面拉取实例, eureka server 不调用其余微服务,所以没必要拉取 fetch-registry: false # 是否将本人注册到 eureka 下面,eureka server 不参加负载平衡,所以没必要注册 register-with-eureka: falseserver: undertow: # 以下的配置会影响buffer,这些buffer会用于服务器连贯的IO操作 # 如果每次须要 ByteBuffer 的时候都去申请,对于堆内存的 ByteBuffer 须要走 JVM 内存调配流程(TLAB -> 堆),对于间接内存则须要走零碎调用,这样效率是很低下的。 # 所以,个别都会引入内存池。在这里就是 `BufferPool`。 # 目前,UnderTow 中只有一种 `DefaultByteBufferPool`,其余的实现目前没有用。 # 这个 DefaultByteBufferPool 绝对于 netty 的 ByteBufArena 来说,非常简单,相似于 JVM TLAB 的机制 # 对于 bufferSize,最好和你零碎的 TCP Socket Buffer 配置一样 # `/proc/sys/net/ipv4/tcp_rmem` (对于读取) # `/proc/sys/net/ipv4/tcp_wmem` (对于写入) # 在内存大于 128 MB 时,bufferSize 为 16 KB 减去 20 字节,这 20 字节用于协定头 buffer-size: 16364 # 是否调配的间接内存(NIO间接调配的堆外内存),这里开启,所以java启动参数须要配置下间接内存大小,缩小不必要的GC # 在内存大于 128 MB 时,默认就是应用间接内存的 directBuffers: true threads: # 设置IO线程数, 它次要执行非阻塞的工作,它们会负责多个连贯, 默认设置每个CPU外围一个读线程和一个写线程 io: 4 # 阻塞工作线程池, 当执行相似servlet申请阻塞IO操作, undertow会从这个线程池中获得线程 # 它的值设置取决于零碎线程执行工作的阻塞系数,默认值是IO线程数*8 worker: 128 # http post body 大小,默认为 -1B ,即不限度 max-http-post-size: -1B # 是否在启动时创立 filter,默认为 true,不必批改 eager-filter-init: true # 限度门路参数数量,默认为 1000 max-parameters: 1000 # 限度 http header 数量,默认为 200 max-headers: 200 # 限度 http header 中 cookies 的键值对数量,默认为 200 max-cookies: 200 # 是否容许 / 与 %2F 本义。/ 是 URL 保留字,除非你的利用明确须要,否则不要开启这个本义,默认为 false allow-encoded-slash: false # 是否容许 URL 解码,默认为 true,除了 %2F 其余的都会解决 decode-url: true # url 字符编码集,默认是 utf-8 url-charset: utf-8 # 响应的 http header 是否会加上 'Connection: keep-alive',默认为 true always-set-keep-alive: true # 申请超时,默认是不超时,咱们的微服务因为可能有长时间的定时工作,所以不做服务端超时,都用客户端超时,所以咱们放弃这个默认配置 no-request-timeout: -1 # 是否在跳转的时候放弃 path,默认是敞开的,个别不必配置 preserve-path-on-forward: false options: # spring boot 没有形象的 xnio 相干配置在这里配置,对应 org.xnio.Options 类 socket: SSL_ENABLED: false # spring boot 没有形象的 undertow 相干配置在这里配置,对应 io.undertow.UndertowOptions 类 server: ALLOW_UNKNOWN_PROTOCOLS: false # access log相干配置 accesslog: # 寄存目录,默认为 logs dir: ./logs/${server.port} # 是否开启 enabled: true # 格局,各种占位符前面会具体阐明 pattern: '{ "transportProtocol":"%{TRANSPORT_PROTOCOL}", "scheme":"%{SCHEME}", "protocol":"%{PROTOCOL}", "method":"%{METHOD}", "reqHeaderUserAgent":"%{i,User-Agent}", "reqHeaderUserId":"%{i,uid}", "traceId":"%{i,X-B3-TraceId}", "spanId":"%{i,X-B3-SpanId}", "queryString": "%q", "uri": "%U", "thread": "%I", "hostPort": "%{HOST_AND_PORT}", "localIp": "%A", "localPort": "%p", "localServerName": "%v", "remoteIp": "%a", "bytesSent": "%b", "time":"%{time,yyyy-MM-dd HH:mm:ss.S}", "status":"%s", "reason":"%{RESPONSE_REASON_PHRASE}", "timeUsed":"%Dms" }' # 文件前缀,默认为 access_log prefix: access. # 文件后缀,默认为 log suffix: log # 是否另起日志文件写 access log,默认为 true # 目前只能依照日期进行 rotate,一天一个日志文件 rotate: truemanagement: endpoint: health: show-details: always endpoints: jmx: exposure: exclude: '*' web: exposure: include: '*'除了同步微服务 undertow 的配置以及 actuator 的配置,Eureka 配置中,因为 Eureka Server 感知其余实例,仅仅通过 eureka.client.service-url 这个配置读取,所以不须要 eureka server 注册到 eureka server 或者读取 eureka server 下面的实例,因而这里咱们配置不注册也不读取。而后,咱们这里依照之前剖析的,敞开了自我爱护,开启了定时过期工作,并且将相干的定时工作工夫距离都调低了不少,因为咱们的集群不是万个实例级别的,而是一千左右,所以能够调高这些工作频率。 ...

August 25, 2021 · 3 min · jiezi

关于spring-cloud:SpringCloud升级之路20200x版19Eureka的服务端设计与配置

本系列代码地址:https://github.com/HashZhang/... Eureka Server 配置是 Eureka Server 须要的一些配置,包含之前屡次提到的定时查看实例过期的配置,自我爱护相干的配置,同一 zone 内集群相干的配置和跨 zone 相干的配置。在 Spring Cloud 中,Eureka 客户端配置以 eureka.server 结尾,对应配置类为 EurekaServerConfigBean 依据上一节 Eureka 客户端剖析,咱们晓得 Eureka 客户端次要拜访如下几个接口: 注册:POST /eureka/apps/appID心跳:PUT /eureka/apps/appID/instanceID获取所有服务实例:GET /eureka/apps增量获取所有服务实例:GET /eureka/apps/deltaEureka Server 解决这些申请的外围逻辑,以及相干配置如下图所示: 实例注册后须要发送心跳证实这个实例是活着的,Eureka Server 中也有定时工作查看实例是否曾经过期。 eureka: server: #被动查看服务实例是否生效的工作执行距离,默认是 60s eviction-interval-timer-in-ms: 3000 #这个配置在两个中央被应用: #如果启用用了自我爱护,则会 renewal-threshold-update-interval-ms 指定的工夫内,收到的心跳申请个数是否小于实例个数乘以这个 renewal-percent-threshold #定时工作查看过期实例,每次最多过期 1 - renewal-percent-threshold 这么多比例的实例 renewal-percent-threshold: 0.85 服务器中有定时过期的工作,查看迟迟没有心跳的实例,并登记他们。自我爱护次要针对集群中网络呈现问题,导致有很多实例无奈发送心跳导致很多实例状态异样,然而理论实例还在失常工作的状况,不要让这些实例不参加负载平衡。 eureka: server: #留神,最好所有的客户端实例配置的心跳工夫相干的配置,是雷同的。这样应用自我爱护的个性最精确。 #敞开自我爱护 #咱们这里不应用自我爱护,因为: #自我爱护次要针对集群中网络呈现问题,导致有很多实例无奈发送心跳导致很多实例状态异样,然而理论实例还在失常工作的状况,不要让这些实例不参加负载平衡 #启用自我爱护的状况下,就会进行对于实例的过期 #然而,如果呈现这种状况,其实也代表很多实例无奈读取注册核心了。 #并且还有一种状况就是,Eureka 重启。尽管不常见,然而对于镜像中其余的组件更新咱们还是很频繁的 #我偏向于从客户端对于实例缓存机制来解决这个问题,如果返回实例列表为空,则应用上次的实例列表进行负载平衡,这样既能解决 Eureka 重启的状况,又能解决一些 Eureka 网络隔离的状况 #自我保护模式基于每分钟须要收到 renew (实例心跳)申请个数,如果启用了自我保护模式,只有上一分钟接管到的 renew 个数,大于这个值,实例过期才会被登记 enable-self-preservation: false # 每分钟须要收到 renew (实例心跳)申请个数是须要动静刷新的,这个刷新距离就是 renewal-threshold-update-interval-ms #更新流程大略是:计算以后一共有多少实例,如果大于之前冀望的实例量 * renewal-percent-threshold(或者没开启自我保护模式),则更新冀望的实例数量为以后一共有多少实例 #之后依据冀望的实例数量,计算冀望须要收到的实例心跳申请个数 = 冀望的实例数量 * (60 / expected-client-renewal-interval-seconds) * renewal-percent-threshold #公式中 60 代表一分钟,因为公式用到了 expected-client-renewal-interval-seconds,也就是实例均匀心跳距离,为了使这个公式精确,最好每个实例配置一样的心跳工夫 #默认 900000ms = 900s = 15min renewal-threshold-update-interval-ms: 900000 #下面提到的实例均匀心跳距离,或者说是冀望的心跳距离,为了使这个公式精确,最好每个实例配置一样的心跳工夫 #默认 30s expected-client-renewal-interval-seconds: 30 #这个配置在两个中央被应用: #如果启用用了自我爱护,则会 renewal-threshold-update-interval-ms 指定的工夫内,收到的心跳申请个数是否小于实例个数乘以这个 renewal-percent-threshold #定时工作查看过期实例,每次最多过期 1 - renewal-percent-threshold 这么多比例的实例 renewal-percent-threshold: 0.85 ...

August 24, 2021 · 2 min · jiezi

关于spring-cloud:SpringCloud升级之路20200x版18Eureka的客户端核心设计和配置

本系列代码地址:https://github.com/HashZhang/... Eureka 客户端配置就是拜访 Eureka Server 的客户端相干配置,包含 Eureka Server 地址的配置,拉取服务实例信息相干配置,以后实例注册相干配置和 http 连贯相干配置。在 Spring Cloud 中,Eureka 客户端配置以 eureka.client 结尾,对应配置类为 EurekaClientConfigBean 其中,Eureka 客户端有三个比拟重要的定时工作,以及相干配置,这里用图的形式给大家展现进去了: 读取服务实例相干流程: 定时查看实例信息以及实例状态并同步到 Eureka Server: 定时心跳相干流程: 能够间接指定 Eureka Server 的地址,并且,这些配置能够动静批改,并且能够配置刷新工夫。例如: eureka: client: service-url: # 默认eureka集群,这里必须是defaultZone,不能用-替换大写,与其余的配置不一样,因为切实EurekaClientConfigBean外面写死的 defaultZone: http://127.0.0.1:8211/eureka/ zone1: http://127.0.0.1:8212/eureka/ zone2: http://127.0.0.1:8213/eureka/ zone3: http://127.0.0.1:8214/eureka/ # 如果下面 eureka server 地址相干配置更新了,多久之后会从新读取感知到 eureka-service-url-poll-interval-seconds: 300也能够通过 DNS 获取 Eureka Server,例如: eureka: client: # 是否应用 dns 获取,如果指定了则通过上面的 dns 配置获取,而不是下面的 service-url use-dns-for-fetching-service-urls: true # dns 配置 # eureka-server-d-n-s-name: eureka.com # dns 配置的 eureka server 的 port # eureka-server-port: 80 # dns 配置的 eureka server 的 port 前面的 uri 前缀 context # eureka-server-u-r-l-context: /eureka同时,可能有不同的 Eureka Server 部署在不同的可用区域(zone)上,这里也能够配置 Eureka Client 的 zone 配置: ...

August 23, 2021 · 2 min · jiezi

关于spring-cloud:SpringCloud升级之路20200x版16Eureka架构和核心概念

本系列代码地址:https://github.com/HashZhang/... Eureka 目前 1.x 版本还在更新,然而应该不会更新新的性能了,只是对现有性能进行保护,降级并兼容所需的依赖。 Eureka 2.x 曾经胎死腹中了。然而,这也不代表 Eureka 就是不能用了。如果你须要一个简便易于部署的注册核心,Eureka 还是一个很好的抉择。云服务环境中,基本上所有实例地址和微服务名称都在一直变动,也并不太须要 Eureka 所短少的长久化个性。当你的集群属于中小规模的时候(节点小于 1000 个), Eureka 仍然是一个不错的抉择。当你的集群很大的时候,Eureka 的同步机制可能就限度了他的体现。 Eureka 的设计比拟玲珑,没有简单的同步机制(例如 Nacos 基于 Raft,Zookeeper 基于 Zab),也没有简单的长久化机制,集群关系只是简略的将收到的客户端申请转发到集群内的其余 Eureka 实例。Eureka 自身也只有注册核心的性能,不像其余品种的注册核心那样,将注册核心和配置核心合在一起,例如 Consul 和 nacos。 这里咱们疏忽所有的 AWS 相干的术语以及配置还有相干逻辑解决。 Eureka 中的术语: Eureka 实例:每个注册到 Eureka 下面的实例就是 Eureka 实例。Eureka 实例状态:包含 UP(能够解决申请),DOWN(健康检查失败,不能失常解决申请),STARTING(启动中,不能解决申请),OUT_OF_SERVICE(人为下线,临时不解决申请),UNKNOWN(未知状态)。Eureka 服务器:作为注册核心运行,次要提供实例治理性能(解决实例注册(register)申请、解决实例登记(cancel)申请、解决实例心跳(renew)申请、外部解决实例过期(evict))、实例查问性能(各种查问实例信息的接口,例如通过 AppName 获取实例列表,通过实例 id 获取实例信息等等)Eureka 服务器集群:Eureka 服务器的集群,每个 Eureka 服务器都配置了区域以及可用区,Eureka 服务器收到的客户端申请会转发到同一区域内的其余 Eureka 服务器,能够配置优先发到同一可用区的 Eureka 服务器。非同一区域内 Eureka 服务器,通过定时拉取的形式进行同步。Eureka 客户端:申请 Eureka 服务器的客户端。封装发送实例注册(register)申请、实例登记(cancel)申请和实例心跳(renew)申请。VIP(或者是 Virtual Hostname): Eureka 中能够通过两种形式获取实例,一个是通过服务名称,另一种是通过 VIP。每个实例都有服务名称,以及 VIP。Eureka 服务器中的索引形式是以服务名称为 key 的索引,咱们也能够通过遍历所有实例信息的形式通过 VIP 字符串匹配获取相干的实例。在 Spring Cloud 体系中,一个实例的 VIP、SVIP(其实就是 Secure VIP,即 https 的地址)以及服务名称都是 spring.application.name 指定的服务名称。 ...

August 20, 2021 · 1 min · jiezi

关于springcloud:SpringCloud升级之路20200x版15UnderTow-订制

本系列代码地址:https://github.com/HashZhang/...咱们应用 Spring Boot 的 SPI 机制对 Undertow 进行订制,次要有如下两个方面: 须要在 accesslog 中关上响应工夫统计。冀望通过 JFR 监控每个 Http 申请,同时占用空间不能太大。接下来咱们顺次实现这两个需要: 首先,咱们的框架作为根底组件,应该依照根底组件的规范来开发,应用 这个系列之前介绍的 spring.factories 这个 Spring Boot SPI 机制,在引入咱们这个根底组件依赖的时候,就主动加载对应配置。 而后,对于是否关上响应工夫统计,应该依据用户配置的 accesslog 格局而定(Undertow 的 accesslog 配置能够参考这个系列之前的文章)。 由此咱们来编写代码。目前比拟遗憾的是,Spring Boot 对接 Undertow 并没有间接的配置能够让 Undertow 关上响应工夫统计,然而能够通过实现 WebServerFactoryCustomizer 接口的形式,对结构 WebServer 的 WebServerFactory 进行订制。其底层实现原理非常简单(以下参考源码:WebServerFactoryCustomizerBeanPostProcessor.java): Spring Boot 中指定了 WebServerFactoryCustomizerBeanPostProcessor 这个 BeanPostProcessor.WebServerFactoryCustomizerBeanPostProcessor 的 postProcessBeforeInitialization 办法(即在所有 Bean 初始化之前会调用的办法)中,如果 Bean 类型是 WebServerFactory,就将其作为参数传入注册的所有 WebServerFactoryCustomizer Bean 中进行自定义。接下来咱们来实现自定义的 WebServerFactoryCustomizer DefaultWebServerFactoryCustomizer package com.github.hashjang.spring.cloud.iiford.spring.cloud.webmvc.undertow;import io.undertow.UndertowOptions;import org.apache.commons.lang.StringUtils;import org.springframework.boot.autoconfigure.web.ServerProperties;import org.springframework.boot.web.embedded.undertow.ConfigurableUndertowWebServerFactory;import org.springframework.boot.web.server.WebServerFactoryCustomizer;public class DefaultWebServerFactoryCustomizer implements WebServerFactoryCustomizer<ConfigurableUndertowWebServerFactory> { private final ServerProperties serverProperties; public DefaultWebServerFactoryCustomizer(ServerProperties serverProperties) { this.serverProperties = serverProperties; } @Override public void customize(ConfigurableUndertowWebServerFactory factory) { String pattern = serverProperties.getUndertow() .getAccesslog().getPattern(); // 如果 accesslog 配置中打印了响应工夫,则关上记录申请开始工夫配置 if (logRequestProcessingTiming(pattern)) { factory.addBuilderCustomizers(builder -> builder.setServerOption( UndertowOptions.RECORD_REQUEST_START_TIME, true ) ); } } private boolean logRequestProcessingTiming(String pattern) { //如果没有配置 accesslog,则间接返回 false if (StringUtils.isBlank(pattern)) { return false; } //目前只有 %D 和 %T 这两个占位符和响应工夫无关,通过这个判断 //其余的占位符信息,请参考系列之前的文章 return pattern.contains("%D") || pattern.contains("%T"); }}而后咱们通过 spring.factories SPI 机制将这个类以一个单例 Bean 的模式,注册到咱们利用 ApplicationContext 中,如图所示: ...

August 19, 2021 · 3 min · jiezi

关于spring-cloud:SpringCloud升级之路20200x版13UnderTow-核心配置

本系列代码地址:https://github.com/HashZhang/... Undertow 的配置能够参考 Undertow 的 Builder,并且其中也有一些默认的配置参数: Undertow private Builder() { ioThreads = Math.max(Runtime.getRuntime().availableProcessors(), 2); workerThreads = ioThreads * 8; long maxMemory = Runtime.getRuntime().maxMemory(); //smaller than 64mb of ram we use 512b buffers if (maxMemory < 64 * 1024 * 1024) { //use 512b buffers directBuffers = false; bufferSize = 512; } else if (maxMemory < 128 * 1024 * 1024) { //use 1k buffers directBuffers = true; bufferSize = 1024; } else { //use 16k buffers for best performance //as 16k is generally the max amount of data that can be sent in a single write() call directBuffers = true; bufferSize = 1024 * 16 - 20; //the 20 is to allow some space for protocol headers, see UNDERTOW-1209 }}ioThreads 大小为可用 CPU 数量 * 2,即 Undertow 的 XNIO 的读线程个数为可用 CPU 数量,写线程个数也为可用 CPU 数量。workerThreads 大小为 ioThreads 数量 * 8.如果内存大小小于 64 MB,则不应用间接内存,bufferSize 为 512 字节如果内存大小大于 64 MB 小于 128 MB,则应用间接内存,bufferSize 为 1024 字节如果内存大小大于 128 MB,则应用间接内存,bufferSize 为 16 KB 减去 20 字节,这 20 字节用于协定头。 ...

August 17, 2021 · 3 min · jiezi

关于springcloud:SpringCloud升级之路20200x版12UnderTow-简介与内部原理

本系列代码地址:https://github.com/HashZhang/... 在咱们的我的项目中,咱们没有采纳默认的 Tomcat 容器,而是应用了 UnderTow 作为咱们的容器。其实性能上的差别并没有那么显著,然而应用 UnderTow 咱们能够利用间接内存作为网络传输的 buffer,缩小业务的 GC,优化业务的体现。其实 Tomcat 也有应用间接内存作为网络传输的 buffer 的配置,即 Connector 应用 NIO 或者 NIO2,还有 APR 这种基于 JNI 的优化文件与申请传输的形式,然而 tomcat 随着一直迭代与倒退,性能越来越欠缺以及组件化的同时,架构也越来越简单,这也带来了代码设计与品质上的一些升高。比照 Tomcat Connector 那里的源代码与设计,我最终抉择了更为轻量设计的 Undertow。至于不选 Jetty 的起因和 Tomcat 相似,不选 reactor-netty 的次要起因是我的项目还是比拟新并且不太成熟,并且基于异步回调,很多时候异样解决不全面,导致最初诡异的响应并且异样定位老本比拟高。 Undertow 的官网:https://undertow.io/ 红帽开源产品,目前是 WildFly(JBoss AS)的默认 Web 容器。在不须要非常复杂的配置状况下,能够展现出很高的性能以及稳定性。十分轻量,只需通过 API 即可疾速搭建 Web 服务器。底层基于 XNIO,和 Netty 设计相似,应用 NIO 作为网络交互的形式,并且应用间接内存作为网络传输的 buffer,缩小业务的 GC。因为基于这种异步框架,所以配置也是交由链式Handler配置和解决申请,能够最小化按需加载模块,毋庸加载多余性能反对 Servlet 4.0 以及向下兼容,反对 WebSocket然而,Undertow 有一些令人担忧的中央: 官网一股贫困的气味,背靠红帽这个不太靠谱的爹NIO 框架采纳的是 XNIO,在官网 3.0 roadmap 申明中提到了将会在 3.0 版本开始,从 XNIO 迁徙到 netty, 参考:Undertow 3.0 Announcement。然而,目前曾经过了快两年了,3.0 还是没有公布,并且 github 上 3.0 的分支曾经一年多没有更新了。目前,还是在用 2.x 版本的 Undertow。不晓得是 3.0 目前没必要开发,还是胎死腹中了呢?目前国内的环境对于 netty 应用更加宽泛并且大部分人对于 netty 更加相熟一些, XNIO 利用并不是很多。不过,XNIO 的设计与 netty 大同小异。官网文档的更新比较慢,可能会慢 1~2 个小版本,导致 Spring Boot 粘合 Undertow 的时候,配置显得不会那么优雅。参考官网文档的同时,最好还是看一下源码,至多看一下配置类,能力搞懂到底是怎么设置的。认真看 Undertow 的源码,会发现有很多防御性编程的设计或者功能性设计 Undertow 的作者想到了,然而就是没实现,有很多没有实现的半成品代码。这也令人担心 Underow 是否开发能源有余,哪一天会忽然死掉?不过,幸好有 spring-boot,在 spring-boot 我的项目中,切换容器的老本不大,批改依赖即可。同时要留神,不同 web 容器的配置。 ...

August 16, 2021 · 2 min · jiezi

关于spring-cloud:05篇-Nacos-Client服务订阅之事件机制剖析

学习不必那么功利,二师兄带你从更高维度轻松浏览源码~上篇文章,咱们剖析了Nacos客户端订阅的外围流程:Nacos客户端通过一个定时工作,每6秒从注册核心获取实例列表,当发现实例发生变化时,公布变更事件,订阅者进行业务解决,而后更新内存中和本地的缓存中的实例。 这篇文章为服务订阅的第二篇,咱们重点来剖析,定时工作获取到最新实例列表之后,整个事件机制是如何解决的。 回顾整个流程先回顾一下客户端服务订阅的根本流程: 在第一步调用subscribe办法时,会订阅一个EventListener事件。而在定时工作UpdateTask定时获取实例列表之后,会调用ServiceInfoHolder#processServiceInfo办法对ServiceInfo进行本地解决,这其中就包含和事件处理。 监听事件的注册在subscribe办法中,通过如下形式进行了监听事件的注册: @Overridepublic void subscribe(String serviceName, String groupName, List<String> clusters, EventListener listener) throws NacosException { if (null == listener) { return; } String clusterString = StringUtils.join(clusters, ","); changeNotifier.registerListener(groupName, serviceName, clusterString, listener); clientProxy.subscribe(serviceName, groupName, clusterString);}这里的changeNotifier.registerListener便是进行具体的事件注册逻辑。追进去看一下实现源码: // InstancesChangeNotifierpublic void registerListener(String groupName, String serviceName, String clusters, EventListener listener) { String key = ServiceInfo.getKey(NamingUtils.getGroupedName(serviceName, groupName), clusters); ConcurrentHashSet<EventListener> eventListeners = listenerMap.get(key); if (eventListeners == null) { synchronized (lock) { eventListeners = listenerMap.get(key); if (eventListeners == null) { eventListeners = new ConcurrentHashSet<EventListener>(); // 将EventListener缓存到listenerMap listenerMap.put(key, eventListeners); } } } eventListeners.add(listener);}能够看出,事件的注册便是将EventListener存储在InstancesChangeNotifier的listenerMap属性当中了。 ...

August 16, 2021 · 4 min · jiezi

关于springcloud:SpringCloud升级之路20200x版11Log4j2-监控相关

本系列代码地址:https://github.com/HashZhang/... Log4j2 异步日志外围通过 RingBuffer 实现,如果某一时刻产生大量日志并且写的速度不及时导致 RingBuffer 满了,业务代码中调用日志记录的中央就会阻塞。所以咱们须要对 RingBuffer 进行监控。Log4j2 对于每一个 AsyncLogger 配置,都会创立一个独立的 RingBuffer,例如上面的 Log4j2 配置: <!--省略了除了 loggers 以外的其余配置--> <loggers> <!--default logger --> <Asyncroot level="info" includeLocation="true"> <appender-ref ref="console"/> </Asyncroot> <AsyncLogger name="RocketmqClient" level="error" additivity="false" includeLocation="true"> <appender-ref ref="console"/> </AsyncLogger> <AsyncLogger name="com.alibaba.druid.pool.DruidDataSourceStatLoggerImpl" level="error" additivity="false" includeLocation="true"> <appender-ref ref="console"/> </AsyncLogger> <AsyncLogger name="org.mybatis" level="error" additivity="false" includeLocation="true"> <appender-ref ref="console"/> </AsyncLogger></loggers>这个配置蕴含 4 个 AsyncLogger,对于每个 AsyncLogger 都会创立一个 RingBuffer。Log4j2 也思考到了监控 AsyncLogger 这种状况,所以将 AsyncLogger 的监控裸露成为一个 MBean(JMX Managed Bean)。 相干源码如下: Server.java private static void registerLoggerConfigs(final LoggerContext ctx, final MBeanServer mbs, final Executor executor) throws InstanceAlreadyExistsException, MBeanRegistrationException, NotCompliantMBeanException { //获取 log4j2.xml 配置中的 loggers 标签下的所有配置值 final Map<String, LoggerConfig> map = ctx.getConfiguration().getLoggers(); //遍历每个 key,其实就是 logger 的 name for (final String name : map.keySet()) { final LoggerConfig cfg = map.get(name); final LoggerConfigAdmin mbean = new LoggerConfigAdmin(ctx, cfg); //对于每个 logger 注册一个 LoggerConfigAdmin register(mbs, mbean, mbean.getObjectName()); //如果是异步日志配置,则注册一个 RingBufferAdmin if (cfg instanceof AsyncLoggerConfig) { final AsyncLoggerConfig async = (AsyncLoggerConfig) cfg; final RingBufferAdmin rbmbean = async.createRingBufferAdmin(ctx.getName()); register(mbs, rbmbean, rbmbean.getObjectName()); } }}创立的 MBean 的类源码:RingBufferAdmin.java ...

August 15, 2021 · 3 min · jiezi

关于springcloud:SpringCloud升级之路20200x版8理解-NamedContextFactory

本系列为之前系列的整顿重启版,随着我的项目的倒退以及我的项目中的应用,之前系列外面很多货色产生了变动,并且还有一些货色之前系列并没有提到,所以重启这个系列重新整理下,欢送各位留言交换,谢谢!~spring-cloud-commons 中参考了 spring-cloud-netflix 的设计,引入了 NamedContextFactory 机制,个别用于对于不同微服务的客户端模块应用不同的 子 ApplicationContext 进行配置。 spring-cloud-commons 是 Spring Cloud 对于微服务根底组件的形象。在一个微服务中,调用微服务 A 与调用微服务 B 的配置可能不同。比较简单的例子就是,A 微服务是一个简略的用户订单查问服务,接口返回速度很快,B 是一个报表微服务,接口返回速度比较慢。这样的话咱们就不能对于调用微服务 A 和微服务 B 应用雷同的超时工夫配置。还有就是,咱们可能对于服务 A 通过注册核心进行发现,对于服务 B 则是通过 DNS 解析进行服务发现,所以对于不同的微服务咱们可能应用不同的组件,在 Spring 中就是应用不同类型的 Bean。 在这种需要下,不同微服务的客户端有不同的以及雷同的配置,有不同的 Bean,也有雷同的 Bean。所以,咱们能够针对每一个微服务将他们的 Bean 所处于 ApplicationContext 独立开来,不同微服务客户端应用不同的 ApplicationContext。NamedContextFactory 就是用来实现这种机制的。 编写源码: package com.github.hashjang.spring.cloud.iiford.service.common;import org.junit.Assert;import org.junit.Test;import org.springframework.cloud.context.named.NamedContextFactory;import org.springframework.context.annotation.AnnotationConfigApplicationContext;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.core.env.Environment;import java.util.List;import java.util.Objects;public class CommonNameContextTest { private static final String PROPERTY_NAME = "test.context.name"; @Test public void test() { //创立 parent context AnnotationConfigApplicationContext parent = new AnnotationConfigApplicationContext(); //增加 BaseConfig 相干配置 parent.register(BaseConfig.class); //初始化 parent parent.refresh(); //创立 testClient1,默认配置应用 ClientCommonConfig TestClient testClient1 = new TestClient(ClientCommonConfig.class); //创立 service1 与 service2 以及指定对应额定的配置类 TestSpec testSpec1 = new TestSpec("service1", new Class[]{Service1Config1.class, Service1Config2.class}); TestSpec testSpec2 = new TestSpec("service2", new Class[]{Service2Config.class}); //设置 parent ApplicationContext 为 parent testClient1.setApplicationContext(parent); //将 service1 与 service2 的配置退出 testClient1 testClient1.setConfigurations(List.of(testSpec1, testSpec2)); BaseBean baseBean = testClient1.getInstance("service1", BaseBean.class); System.out.println(baseBean); //验证失常获取到了 baseBean Assert.assertNotNull(baseBean); ClientCommonBean commonBean = testClient1.getInstance("service1", ClientCommonBean.class); System.out.println(commonBean); //验证失常获取到了 commonBean Assert.assertNotNull(commonBean); Service1Bean1 service1Bean1 = testClient1.getInstance("service1", Service1Bean1.class); System.out.println(service1Bean1); //验证失常获取到了 service1Bean1 Assert.assertNotNull(service1Bean1); Service1Bean2 service1Bean2 = testClient1.getInstance("service1", Service1Bean2.class); System.out.println(service1Bean2); //验证失常获取到了 service1Bean2 Assert.assertNotNull(service1Bean2); BaseBean baseBean2 = testClient1.getInstance("service2", BaseBean.class); System.out.println(baseBean2); //验证失常获取到了 baseBean2 并且 baseBean2 就是 baseBean Assert.assertEquals(baseBean, baseBean2); ClientCommonBean commonBean2 = testClient1.getInstance("service2", ClientCommonBean.class); System.out.println(commonBean2); //验证失常获取到了 commonBean2 并且 commonBean 和 commonBean2 不是同一个 Assert.assertNotNull(commonBean2); Assert.assertNotEquals(commonBean, commonBean2); Service2Bean service2Bean = testClient1.getInstance("service2", Service2Bean.class); System.out.println(service2Bean); //验证失常获取到了 service2Bean Assert.assertNotNull(service2Bean); } @Configuration(proxyBeanMethods = false) static class BaseConfig { @Bean BaseBean baseBean() { return new BaseBean(); } } static class BaseBean {} @Configuration(proxyBeanMethods = false) static class ClientCommonConfig { @Bean ClientCommonBean clientCommonBean(Environment environment, BaseBean baseBean) { //在创立 NamedContextFactory 外面的子 ApplicationContext 的时候,会指定 name,这个 name 对应的属性 key 即 PROPERTY_NAME return new ClientCommonBean(environment.getProperty(PROPERTY_NAME), baseBean); } } static class ClientCommonBean { private final String name; private final BaseBean baseBean; ClientCommonBean(String name, BaseBean baseBean) { this.name = name; this.baseBean = baseBean; } @Override public String toString() { return "ClientCommonBean{" + "name='" + name + '\'' + ", baseBean=" + baseBean + '}'; } } @Configuration(proxyBeanMethods = false) static class Service1Config1 { @Bean Service1Bean1 service1Bean1(ClientCommonBean clientCommonBean) { return new Service1Bean1(clientCommonBean); } } static class Service1Bean1 { private final ClientCommonBean clientCommonBean; Service1Bean1(ClientCommonBean clientCommonBean) { this.clientCommonBean = clientCommonBean; } @Override public String toString() { return "Service1Bean1{" + "clientCommonBean=" + clientCommonBean + '}'; } } @Configuration(proxyBeanMethods = false) static class Service1Config2 { @Bean Service1Bean2 service1Bean2() { return new Service1Bean2(); } } static class Service1Bean2 { } @Configuration(proxyBeanMethods = false) static class Service2Config { @Bean Service2Bean service2Bean(ClientCommonBean clientCommonBean) { return new Service2Bean(clientCommonBean); } } static class Service2Bean { private final ClientCommonBean clientCommonBean; Service2Bean(ClientCommonBean clientCommonBean) { this.clientCommonBean = clientCommonBean; } @Override public String toString() { return "Service2Bean{" + "clientCommonBean=" + clientCommonBean + '}'; } } static class TestSpec implements NamedContextFactory.Specification { private final String name; private final Class<?>[] configurations; public TestSpec(String name, Class<?>[] configurations) { this.name = name; this.configurations = configurations; } @Override public String getName() { return name; } @Override public Class<?>[] getConfiguration() { return configurations; } } static class TestClient extends NamedContextFactory<TestSpec> { public TestClient(Class<?> defaultConfigType) { super(defaultConfigType, "testClient", PROPERTY_NAME); } }}后果输入为: ...

August 10, 2021 · 4 min · jiezi

关于spring-cloud:第一章-微服务简介

本章从架构倒退的角度来形容技术的倒退过程,依据不同阶段所面临的问题来推动架构的演变,从而更好地了解微服务的实质以及它所带来的的益处,本章内容次要会通过架构的演进过程帮忙大家建设一个整体意识,从而更好地把握微服务体系。 1.1 从单体架构到微服务架构的演进 1.1.1 单体架构 通过咱们之前的学习,咱们开发一个一个Web我的项目,能够应用Spring、SpringMVC、Mybatis等技术。比方之前的快递驿站我的项目,旅游网我的项目SSM版,账单治理我的项目等,我的项目构造如下图1-1所示。 图1-1 单体架构整个零碎的架构非常简单,应用Spring+SpringMVC+Mybatis构建一个根底工程、MySQL数据库作为长久化存储,在这个工程中创立不同的Service实现商场中不同的业务场景,如线路、线路分类、用户等。最初把我的项目构建成一个war包部署在Tomcat容器上即可应用,这时咱们之前常常采纳的架构。通常来说,如果一个war包或者jar包外面蕴含一个利用的所有性能,则咱们称这种架构为单体架构。很多传统互联网公司或者守业型公司晚期根本都会采纳这样的架构,因为这样的架构足够简略,可能疾速开发和上线。而且对于我的项目初期用户量不大的状况,这样的架构足以撑持业务的失常运行。 1.1.2 集群和垂直化 以商城零碎为例。随着业务的倒退,产品被越来越多的人应用,那么对于整个技术架构来说,可能会面临以下挑战:用户量越来越大,网络访问量一直增大,导致后端服务器的负载越来越高。用户量大了,产品须要满足不同用户的需要来留住用户,使得业务场景越来越多并且越来越简单。当服务器的负载越来越高的时候,如果不进行任何解决,用户在网站上操作的响应会越来越慢,甚至呈现无法访问的状况,对于十分重视用户体验的互联网产品来说,这是无奈容忍的。业务的场景越多越简单,意味着war包中的代码量会持续上升,并且各个业务代码之间的耦合度也会越来越高,前期的代码保护和版本公布波及的测试和上线,也会很困那。举个最简略的例子,当你须要在库存模块外面增加一个办法时,带来的影响是须要把整个零碎从新测试和部署,而当一个war包有几GB的大小时,部署的过程也是相当苦楚的。因而,咱们能够从两个方面进行优化:通过横向减少服务器,把单台机器变成多台机器的集群。依照业务的垂直畛域进行拆分,缩小业务的耦合度,以及升高单个war包带来的伸缩性艰难问题。如图1-2所示,咱们把商城零碎依照业务维度进行了垂直拆分:用户子系统、库存子系统、商品子系统,每个子系统由不同的业务团队负责保护并且独立部署。同时,咱们针对Tomcat服务器进行了集群部署,也就是把多台Tomcat服务器通过网络进行连贯组合,造成一个整体对外提供服务。这样做的益处是可能在扭转利用自身的前提下,通过减少服务器来进行程度扩容从而晋升整个零碎的吞吐量。须要留神的是,图1-2中针对数据库进行了垂直分库,次要是思考到Tomcat服务器可能承载的流量大了之后,如果流量都传导到数据库上,会给数据库造成比拟大的压力。总体来说,数据库层面的拆分思维和业务零碎的拆分思维是一样的,都是采纳分而治之的思维。 图1-2 集群及垂直化之后的架构1.1.3 SOA为了让大家更好地了解SOA,咱们来看两个场景:假如一个用户执行下单操作,零碎的解决逻辑是先去库存子系统检杳商品的库存,只有在库存足够的状况下才会提交订单,那么这个查看库存的逻辑是放在订单子系统中还是库存子系统呢?在整个零碎中,肯定会存在十分多相似的共享业务的场景,这些业务场景的逻辑必定会被反复创立,从而产生十分多冗余的业务代码,这些冗余代码的保护老本会随着工夫的推移越来越高,能不能够把这些共享业务逻辑抽离进去造成可重用的服务呢?在一个集团公司下有很多子公司,每个子公司都有本人的业务模式和信息积淀,各个子公司之间不进行交互和共享。这个时候每个子公司尽管可能发明肯定的价值,然而因为各个子公司之间信息不是互联互通的,彼此之间造成了信息孤岛,使得价值无奈最大化。基于这些问题,就引入了SOA (Service-Oriented Architecture ),也就是面向服务的架构,从语义上说,它和面向过程、面向对象、面向组件的思维是一样的,都是一种软件组建及开发的形式。外围指标是把一些通用的、会被多个下层服务调用的共享业务提取成独立的根底服务。这些被提取进去的共享服务相对来说比拟独立,并且能够重用。所以在SOA中,服务是最外围的形象伎俩,业务被划分为一些粗粒度的业务服务和业务流程。如图1-3所示,提取出了用户服务、库存服务、商品服务等多个共享服务。在SOA中,会采纳ESB (企业服务总线)来作为零碎和服务之间的通信桥梁,ESB自身还提供服务地址的治理、不同零碎之间的协定转化和数据格式转化等。调用端不离要关怀指标服务的地位,从而使得服务之间的交互是动静的,这样做的益处是实现了服务的调用者和服务的提供者之间的高度解耦。总的来说,SOA次要解决的问题是:信息孤岛。共享业务的重用。 图1-3 SOA架构 1.1.4 微服务架构 业务系统实施服务化革新之后,本来共享的业务被拆分造成可复用的服务,能够在最大水平上防止共享业务的反复建设、资源连贯瓶颈瓶颈等问题。那么被拆分进去的服务是否也须要以业务性能为维度来进行拆分和独立部署,以升高业务的耦合及晋升容错性呢? 微服务就是这样一种解决方案,从名字上来看,面向服务(SOA)和微服务实质上都是服务化思维的一种体现。如果SOA是面向服务开发的思维的雏形,那么微服务就是针对可重用业务服务的更进一步优化,咱们能够把SOA看成微服务的超集,一但服务规模扩充就意味着服务的构建、公布、运维的复杂度也会成倍增加,所以施行微服务的前提是软件交付链路及基础设施的成熟化。因而微服务在我看来并不是一个新的概念,他实质上是服务化思维的最佳实际方向。因为SOA和微服务两者的关注点不一样,造成了这两者有十分大的区别:SOA关注的是服务的重用性及解决信息孤岛问题。微服务关注的是解耦,尽管解耦和可重用性从特定的角度来看是一样的,但实质上是有区别的,解耦是升高业务之间的耦合度,而重用性关注的是服务的复用。微服务会更多地关注在DevOps的继续交付上,因为服务粒度细化之后使得开发运维变得更加重要,因而微服务与容器化技术的联合更加严密。如图1-4所示,将每个具体的业务服务形成可独立运行的微服务,每个微服务只关注某个特定的性能,服务之间采纳轻量级通信机制REST API进行通信。仔细的读者会发现SOA中的服务和微服务架构中的服务粒度是一样的,不是说SOA是微服务的超集吗?其实咱们能够把用户服务拆分的更细,比方用户注册服务、用户鉴权服务等。实际上,微服务到底要拆分到多大的粒度没有对立的规范,更多的时候是须要在粒度和团队之间找均衡的,微服务的粒度越小,服务独立性带来的益处就越多,然而治理大量的微服务也会越简单。 图1-4 微服务1.2 微服务简介 比方咱们网上购物,首先应该去购物网站搜寻商品,这个搜寻性能就能够开发成一个微服务。咱们也能够看到相干商品的举荐,这些举荐项也能够是一个微服务。前面比方退出购物车、下订单、领取等性能都能够开发成一个一个的独立运行的微服务。 In short, the microservice architectural style is an approach to developing a single application as a suite of small services, each running in its own process and communicating with lightweight mechanisms, often an HTTP resource API. These services are built around business capabilities and independently deployable by fully automated deployment machinery. There is a bare minimum of centralized management of these services, which may be written in different programming languages and use different data storage technologies.-- James Lewis and Martin Fowler (2014) ...

August 9, 2021 · 2 min · jiezi

关于springcloud:SpringCloud升级之路20200x版7从Bean到SpringCloud

本系列为之前系列的整顿重启版,随着我的项目的倒退以及我的项目中的应用,之前系列外面很多货色产生了变动,并且还有一些货色之前系列并没有提到,所以重启这个系列重新整理下,欢送各位留言交换,谢谢!~在了解 Spring Cloud 之前,咱们先理解下 Spring 框架、Spring Boot、Spring Cloud 这三者的关系,从一个简略的 Bean,是如何倒退出一个具备微服务个性的 Spring Cloud 的呢? Spring bean 是 Spring 框架在运行时治理的对象。Spring bean 是任何Spring应用程序的根本构建块。你编写的大多数利用程序逻辑代码都将放在Spring bean 中。之后咱们就用 Bean 来简称 Spring bean。 BeanFactory 是 Spring 容器的外围,是一个治理着所有 Bean 的容器。通常状况下,BeanFactory 的实现是应用懒加载的形式,这意味着 Bean 只有在咱们通过 getBean() 办法间接调用获取它们时才进行实例化。 ApplicationContext 在 BeanFactory 的根底上,减少了: 资源定位与加载,基于 ResourcePatternResolver(其实就是带通配符的 ResourceLoader),用来定位并加载各种文件或者网络资源所处环境,基于 EnvironmentCapable。每个 ApplicationContext 都是有 Environment 的,这个 Environment,包含 Profile 定义还有 Properties。Profile 配置是一个被命名的、bean 定义的逻辑组,这些 bean 只有在给定的 profile 配置激活时才会注册到容器。Properties 是 Spring 的属性组,这些属性可能来源于 properties 文件、JVM properties、system环境变量、JNDI、servlet context parameters 上下文参数、专门的 properties 对象,Maps 等等。Bean 的初始化更加残缺的 Bean 生命周期,包含 BeanPostProcessor 以及 BeanFactoryPostProcessor 的各种解决国际化,外围类MessageSource事件公布,基于 ApplicationEventPublisher:将 ApplicationEvent 或者其余类型的事件,发给所有的 Listener能够了解为 ApplicationContext 外部蕴含了一个 BeanFactory,并减少了其余的组件,实现了更丰盛的性能,并且,与 BeanFactory 懒加载的形式不同,它是预加载,所以,每一个 Bean 都在 ApplicationContext 启动之后实例化。 ...

August 9, 2021 · 2 min · jiezi

关于springcloud:SpringCloud升级之路20200x版6微服务特性相关的依赖说明

本系列代码地址:https://github.com/HashZhang/... spring-cloud-common 不再是一个纯依赖的我的项目,这个模块包含: spring-framework-common 的依赖同步与异步微服务公共的依赖同步与异步微服务公共的框架代码革新,这个咱们前面剖析框架以及咱们设计的批改的时候,会详细分析,这里先跳过同步与异步微服务公共的依赖包含: 代码请参考:https://github.com/HashZhang/...1.启用 Spring Cloud 的 Bootstrap Context:在 Spring Cloud 2020.0.x 版本开始,Bootstrap Context 默认不再启用。咱们的我的项目,某些模块应用了 spring-cloud-config,这个是须要启用 Bootstrap Context 的。同时,咱们的配置,还通过 bootstrap.yml 与 application.yml 辨别了不同配置,如果多环境中配置是一样并且根本不会动静更改的则放入 bootstrap.yml,不同环境不同或者可能动静批改则放入 application.yml。所以通过退出如下依赖来启用: <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bootstrap</artifactId></dependency>这个底层实现非常简单,是否启用 Bootstrap Context 是通过查看这个依赖中的 Marker 类是否存在而决定的。参考代码: PropertyUtils.java: /** * Property name for bootstrap marker class name. */public static final String MARKER_CLASS = "org.springframework.cloud.bootstrap.marker.Marker";/** * Boolean if bootstrap marker class exists. */public static final boolean MARKER_CLASS_EXISTS = ClassUtils.isPresent(MARKER_CLASS, null);2.应用 Eureka 作为注册核心,咱们须要增加 Eureka 的客户端依赖: ...

August 8, 2021 · 1 min · jiezi

关于springcloud:聊聊springcloud项目同时存在多个注册中心客户端采坑记

前言前段时间业务部门有这么一个业务场景,他们本人微服务注册核心是用eureka,他们有一些服务接口要调用兄弟部门的接口,他们定了一个服务调用计划,业务部门间接把他们服务注册到兄弟部门的注册核心,而后走rpc调用,兄弟部门注册核心是用nacos。 一开始业务部门研发间接在在pom.xml这么引入 <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency>而后我的项目启动报了如下错 Field registration in org.springframework.cloud.client.serviceregistry.ServiceRegistryAutoConfiguration$ServiceRegistryEndpointConfiguration required a single bean, but 2 were found: - nacosRegistration: defined by method 'nacosRegistration' in class path resource [com/alibaba/cloud/nacos/NacosDiscoveryAutoConfiguration.class] - eurekaRegistration: defined in BeanDefinition defined in class path resource [org/springframework/cloud/netflix/eureka/EurekaClientAutoConfiguration$RefreshableEurekaClientConfiguration.class]业务部门是这么解决的,每次发版时,如果是要纳入兄弟部门的微服务,他们就先手动正文掉eureka的客户端依赖。 起初业务部门就向咱们部门提了一个需要,pom引入多个注册核心客户端,我的项目也要能失常启动 需要剖析从我的项目异样剖析 Field registration in org.springframework.cloud.client.serviceregistry.ServiceRegistryAutoConfiguration$ServiceRegistryEndpointConfiguration required a single bean, but 2 were found: - nacosRegistration: defined by method 'nacosRegistration' in class path resource [com/alibaba/cloud/nacos/NacosDiscoveryAutoConfiguration.class] - eurekaRegistration: defined in BeanDefinition defined in class path resource [org/springframework/cloud/netflix/eureka/EurekaClientAutoConfiguration$RefreshableEurekaClientConfiguration.class]能够看出springcloud默认的服务注册是只反对单服务注册核心。因而咱们解决的计划要么扩大springcloud源码,让它反对多注册核心,要么就是通知springcloud当存在多种注册核心客户端时,抉择一种咱们想要的注册核心客户端 ...

August 3, 2021 · 2 min · jiezi

关于springcloud:一个springcloud微服务商城系统的诞生

起因有一天,苹果和西瓜说:“哎,市面咋没有好用的微服务商城呢?” 西瓜:“太难了呗,你看这个如同是微服务商城耶” 苹果:“这个只有后盾代码,数据库都没” 西瓜:“这个呢” 苹果:“有数据库没前端” 西瓜:“这个呢” 苹果:“有前端,然而是pc的,我要挪动端的” 西瓜:“这个呢” 苹果:“开不了店,不是b2b2c” 西瓜:“这个呢” 苹果:“太旧了,不保护了” 西瓜:“那咱们本人写个吧“ 筹备一个微服务商城应该有啥呢? 答:要拆分服务吧。 拆分之后用啥做服务注册发现呢? 答:spring cloud alibaba 吧,最近挺火的。 都拆开服务了,要分库吧? 答:分,必须分呀。 分完库要解决分布式事务吧? 答:用seata吧,比较简单。谋求性能的时候,用mq实现最终一致性吧。 服务外部调用要用dubbo吧,据说性能挺高的? 答:是呀,不过用http协定会不会好点,毕竟据说dubbo对k8s的兼容不怎么好耶。用http协定,当前革新架构不便呀。 搜寻呢? 答:要分词吧,用es 数据库要同步到es耶,用啥? 答:canal吧 那平安呢?登录权限呢? 答:平安用security,登录之类的本人手写吧,spring security的那套太简单了。 金额呢? 答:用分啦 施行做一个商城的第一步,对立异样解决 原本构想是dubbo的,起初发现dubbo和nacos的兼容性不太好,k8s也有很多dubbo不兼容的坑,决定去除dubbo 引入阿里的代码标准 springcloud2020刚release,迎难而上 简直同时,nacos被爆平安问题,管理员不理不睬的态度,让人愤慨 从新review了一遍平安相干的代码,外部申请封装也进行校验,汲取nacos的教训 seata踩坑 不论性能不性能的问题,rocketmq有事务音讯,rabbitmq要本人写 实现经验了多个框架的替换,多个踩坑,从泛滥不合理中寻求最正当的后果,每一行代码都是独立实现,都有提交记录,我的项目历经快一年,终于进去了!!! 一个基于Spring Cloud、Nacos、Seata、Mysql、Redis、RocketMQ、canal、ElasticSearch、minio的微服务B2B2C电商商城零碎,采纳支流的互联网技术架构、全新的UI设计、反对集群部署、服务注册和发现以及领有残缺的订单流程等,代码齐全开源,没有任何二次封装,是一个非常适合二次开发的电商平台零碎。 一个代码十分标准的微服务商城,应用阿里巴巴代码标准工具扫描,齐全没有异样 目录构造标准咱们也有本人的目录构造 VO(View Object):显示层对象,通常是 Web 向模板渲染引擎层传输的对象。DTO(Data Transfer Object):数据传输对象,前端像后盾进行传输的对象,相似于param。BO(Business Object):业务对象,外部业务对象,只在外部传递,不对外进行传递。Model:模型层,此对象与数据库表构造一一对应,通过 Mapper 层向上传输数据源对象。Controller:次要是对外部访问控制进行转发,各类基本参数校验,或者不复用的业务简略解决等。为了简略起见,一些与事务无关的代码也在这里编写。FeignClient:因为微服务之间存在相互调用,这里是外部申请的接口。Controller:次要是对外部访问控制进行转发,各类基本参数校验,或者不复用的业务简略解决等。为了简略起见,一些与事务无关的代码也在这里编写。Service 层:绝对具体的业务逻辑服务层。Manager 层:通用业务解决层,它有如下特色: 1) 对第三方平台封装的层,预处理返回后果及转化异样信息,适配下层接口。2) 对 Service 层通用能力的下沉,如缓存计划、中间件通用解决。3) 与 DAO 层交互,对多个 DAO 的组合复用。Mapper长久层:数据拜访层,与底层 MySQL进行数据交互。Task层:因为每个服务之间会存在定时工作,比方定时确认收货,定时将流动生效等状况,这外面的Task实际上连贯的是xxl-job(具体能够查看 https://github.com/xuxueli/xx... )进行任务调度。Listener:监听 RocketMQ 进行解决,有时候会监听easyexcel相干数据。对于FeignClient,因为微服务之间存在相互调用,Feign 是http协定,实践上是为理解耦,而实际上提供方接口进行批改,调用方却没有进行批改的时候,会造成异样,所以咱们抽取进去。还有就是对内裸露的接口,是很多中央都专用的,所以咱们还将接口抽取了出了一个模块,不便援用。能够看到mall4cloud-api这个模块下是所有对内feign接口的信息。 ...

August 3, 2021 · 1 min · jiezi

关于springcloud:SpringCloud升级之路20200x版2微服务框架需要考虑的问题

本系列为之前系列的整顿重启版,随着我的项目的倒退以及我的项目中的应用,之前系列外面很多货色产生了变动,并且还有一些货色之前系列并没有提到,所以重启这个系列重新整理下,欢送各位留言交换,谢谢!~ 上图中演示了一个非常简单的微服务架构: 微服务会向注册核心进行注册。微服务从注册核心读取服务实例列表。基于读取到的服务实例列表,微服务之间相互调用。内部拜访通过对立的 API 网关。API 网关从注册核心读取服务实例列表,依据拜访门路调用相应的微服务进行拜访。在这个微服务架构中的每个过程须要实现的性能都在下图中: 接下来咱们一一剖析这个架构中的每个角色波及的性能、要思考的问题以及咱们这个系列应用的库。 每个微服务的根底性能包含: 输入日志,并且在日志中输入链路追踪信息。并且,随着业务压力越来越大,每个过程输入的日志可能越来越多,输入日志可能会成为性能瓶颈,咱们这里应用了 log4j2 异步日志,并且应用了 spring-cloud-sleuth 作为链路追踪的外围依赖。Http 容器:提供 Http 接口的容器,分为针对同步的 spring-mvc 以及针对异步的 spring-webflux 的: 对于 spring-mvc,默认的 Http 容器为 Tomcat。在高并发环境下,申请会有很多。咱们思考通过应用间接内存解决申请来缩小利用 GC 来优化性能,所以没有应用默认的 Tomcat,而是应用 Undertow。对于 spring-webflux,咱们间接应用 webflux 自身作为 Http 容器,其实底层就是 reactor-http,再底层其实就是基于 Http 协定的 netty 服务器。自身就是异步响应式的,并且申请内存根本应用了间接内存。微服务发现与注册:咱们应用了 Eureka 作为注册核心。咱们的集群平时有很多公布,须要疾速感知实例的高低线。同时咱们有很多套集群,每个集群服务实例节点数量是 100 个左右,如果每个集群应用一个 Eureka 集群感觉有些节约,并且咱们心愿能有一个间接治理所有集群节点的治理平台。所以咱们所有集群应用同一套 Eureka,然而通过框架配置保障只有同一集群内的实例相互发现并调用。健康检查:因为 K8s 须要过程提供健康检查接口,咱们应用 Spring Boot 的 actuator 性能,来作为健康检查接口。同时,咱们也通过 Http 裸露了其余 actuator 相干接口,例如动静批改日志级别,热重启等等。指标采集:咱们通过 prometheus 实现过程外部指标采集,并且裸露了 actuator 接口供 grafana 以及 K8s 调用采集。Http 客户端:外部微服务调用都是 Http 调用。每个微服务都须要 Http 客户端。在咱们这里 Http 客户端有: ...

August 2, 2021 · 1 min · jiezi

关于spring-cloud:SpringCloud升级之路20200x版1背景

本系列为之前系列的整顿重启版,随着我的项目的倒退以及我的项目中的应用,之前系列外面很多货色产生了变动,并且还有一些货色之前系列并没有提到,所以重启这个系列重新整理下,欢送各位留言交换,谢谢!~ Spring Cloud 官网文档说了,它是一个残缺的微服务体系,用户能够通过应用 Spring Cloud 疾速搭建一个本人的微服务零碎。那么 Spring Cloud 到底是如何应用的呢?他到底有哪些组件? spring-cloud-commons组件外面,就有 Spring Cloud 默认提供的所有组件性能的形象接口,有的还有默认实现。目前的 2020.0.x (依照之前的命名规定应该是 iiford),也就是spring-cloud-commons-3.0.x包含: 服务发现:DiscoveryClient,从注册核心发现微服务。服务注册:ServiceRegistry,注册微服务到注册核心。负载平衡:LoadBalancerClient,客户端调用负载平衡。其中,重试策略从spring-cloud-commons-2.2.6退出了负载平衡的形象中。断路器:CircuitBreaker,负责什么状况下将服务断路并降级调用 http 客户端:外部 RPC 调用都是 http 调用而后,个别一个残缺的微服务零碎还包含: 对立网关配置核心全链路监控与监控核心Spring Cloud 始终处于十分沉闷,十分疾速迭代的过程,并且 Spring Cloud 高度依赖 Spring Boot,Spring Boot 与 Spring Cloud 相辅相成。然而,疾速迭代带来的不只是新性能的引入以及原有性能的优化,还有就是降级过程中带来了很多兼容性,功能性,完整性,稳定性的懊恼。本系列旨在帮忙广大读者理解不同大版本 Spring Boot & Spring Cloud 的个性性能以及底层原理的同时,应用这些组件实现一个具备残缺性能的微服务体系,同时这个体系会适应目前最新的云原生环境。 咱们应用的是目前最风行的 Docker + Kubernetes 的组合。目前个别微服务架构,都不会间接应用物理机,因为古代的互联网业务个别都具备这样的个性(咱们拿电子商城举例): 业务会在某一时刻开始忽然开始快速增长,例如咱们开始在各地投放广告,用户一直进入网站,随着口碑一直变好,用户增长速度越来越快。业务在一段时间内,有顶峰有低谷。例如在一天内,白天个别都在下班,早晨拜访网站下单的人数比拟多。业务在一段时间内,最高峰与最低峰之间的差距随着业务增长越来越大。因为大部分用户都在早晨拜访网站下单,导致白天和早晨的流量相差越来越大。会忽然呈现流量尖峰,并且很难预测这个工夫点以及估计量。例如双 11 促销的时候,人们大量涌入,很难能预计的好会有多少流量。还有就是忽然大家须要某个商品的时候,例如新冠刚开始的时候,口罩抢购一空。对于这些个性,依据业务压力,智能并且疾速动静扩容缩容这个性能变得越来越重要,然而这个性能在间接部署业务到物理机上很难实现。这时候呈现了虚拟机,将物理机虚拟化形象成多个虚拟机,比方 vmware 和 openstack,咱们能够应用虚拟机在咱们的操作系统中模拟出多台子电脑,子电脑之间是互相隔离的,这样能够更粗疏动静的调配物理机的资源。然而虚拟机对于开发和运维人员而言,还是太过于轻便了,存在启动慢,占用空间大,不易迁徙的毛病。接着,容器化技术应运而生,它不须要虚构出整个操作系统,只须要虚构一个小规模的环境即可,而且启动速度很快,除了运行其中利用以外,根本不耗费额定的系统资源。Docker 是利用最为宽泛的容器技术,通过打包镜像,启动容器来创立一个服务。然而随着利用越来越简单,容器的数量也越来越多,由此衍生了治理运维容器的这个重要场景。这个场景目前最风行的解决方案就是 Kubernetes(k8s)。 Kubernetes 能为咱们提供如下性能: 容器编排与治理,机器资源管理以及存储卷挂载服务的健康检查以及自愈服务弹性扩容配置核心服务发现与调度负载平衡 在咱们公司中,我的项目团队包含了运维团队以及后端开发团队。对于 Docker 镜像打包与治理以及对于 K8s 的开发保护部署,次要交给运维团队。微服务业务开发保护,实现微服务个性的框架的开发保护是交给后端开发团队的。所以对于 K8s 的性能,咱们只应用了前三个,对于配置核心、服务发现与调度还有负载平衡,咱们还是次要交给实现微服务个性的框架实现的,将来可能会将这三个性能应用起来。 微服务框架须要思考与 K8s 的交互,次要是服务的健康检查以及自愈以及服务弹性扩容: ...

August 1, 2021 · 1 min · jiezi

关于spring-cloud:跟二师兄学Nacos吧EXT04篇-Nacos竟然是这样使用代理模式的

学习不必那么功利,二师兄带你从更高维度轻松浏览源码~随着对Nacos源码的深刻浏览,感觉越来越有意思了,大量的设计模式和根底知识点都在其中被使用。不管你是否浏览源码,都值得借鉴一下Nacos的使用案例。 明天这篇文章,给大家介绍一下Nacos Client中对代理模式的使用。浏览这篇文章,你能够不懂Nacos源码,但可能学到代理模式的使用;如果你筹备浏览Nacos源码,不仅能够学到代理模式的案例,还能够更加粗浅的感知到Nacos中的设计思维。 代理模式简介艰深的来讲,代理模式就是让他人(代理)帮忙做你并不关怀的事,作用就相当于日常生活中的中介。 比方,日常生活中,你想买辆车,你能够间接去本人筛选、质检等,但这个过程会消耗你大量的工夫和精力。那么,此时你就能够找一个代理,来帮忙实现筛选、质检的事件。 对于软件设计来说,代理模式的定义为:代理模式给某一个对象提供一个代理对象,并由代理对象管制对原对象的援用。艰深的来讲代理模式就是咱们生存中常见的中介。 代理模式的构造在不应用代理模式时,咱们大略是这样应用一个接口: 客户端在应用CarService接口时须要创立CarServiceImpl类的实例,而后进行业务逻辑解决。 但在某些场景下,一个客户类不想或者不能间接援用一个委托对象(CarServiceImpl),此时代理类对象能够在客户类和委托对象之间起到中介的作用,并提供雷同的性能。 如果提供雷同的性能,那么代理类和委托类就须要实现雷同的接口。此时,上图就演变成了代理模式: 在代理模式的图中,比照一般的间接应用,新增了代理类,并且代理类持有了委托类(实在对象)的援用。代理类自身并不真正实现服务,而是通过调用委托类的相干办法,来提供特定的服务,所以要持有实在类的援用。 代理类能够在业务性能执行的前后退出一些公共的服务,比方负责为委托类预处理音讯、过滤音讯、把音讯转发给委托类,以及预先对返回后果的解决等。 代理模式中的角色: 形象主题类(Subject):申明了指标对象和代理对象的独特接口,在任何能够应用指标对象的中央都能够应用代理对象。具体主题类(RealSubject):也称为委托角色或者被代理角色。定义了代理对象所代表的指标对象。代理类(Proxy):也叫委托类、代理类。代理对象外部含有指标对象的援用,从而能够在任何时候操作指标对象;代理对象提供一个与指标对象雷同的接口,以便能够在任何时候代替指标对象。代理对象通常在客户端调用传递给指标对象之前或之后,执行某个操作,而不是单纯地将调用传递给指标对象。代理模式实现以下面的结构图为例,来看看代理模式的代码实现。 定义形象主题类(CarService)、具体主题类(CarServiceImpl)、代理类(CarServiceProxy): // 形象主题类public interface CarService { // 选车 Car chooseCar(); // 质量检查 boolean qualityCheck();}// 具体主题类public class CarServiceImpl implements CarService { @Override public Car chooseCar() { System.out.println("实在操作:选车"); return new Car(); } @Override public boolean qualityCheck() { System.out.println("实在操作:品质检测"); return true; }}// 代理类public class CarServiceProxy implements CarService { private CarServiceImpl real; public CarServiceProxy() { real = new CarServiceImpl(); } @Override public Car chooseCar() { System.out.println("代理类CarServiceProxy选车:先增加一些日志"); return real.chooseCar(); } @Override public boolean qualityCheck() { System.out.println("代理类CarServiceProxy品质检测:先增加一些日志"); return real.qualityCheck(); }}对应的客户端测试类: ...

July 28, 2021 · 2 min · jiezi

关于springcloud:Spring-CloudSpring-Cloud-AlibabaDubbo的区别

Spring Cloud、Spring Cloud Alibaba、Dubbo的次要区别如下表格所示: 外围组件Spring CloudSpring Cloud AlibabaDubbo服务注册核心Eurekanacoszookeeper/nacos调用形式Rest APIRest APIRPC服务网关Zuulgateway无断路器HystrixSentinel不欠缺分布式配置Spring Cloud Confignaco无分布式追踪零碎SleuthSleuth无音讯总线BusBus RocketMQ无数据流StreamStream无批量工作TaskTask无消息中间件无RecketMQ无分布式事务解决方案无SeataSeata散布式调度服务无Alibaba Cloud SchedulerX无短信平台无Alibaba Cloud SMS无对于Dubbo与Spring Cloud的区别,可参考博客:https://www.cnblogs.com/aspir...Spring Cloud Alibaba是对Spring Cloud中局部进行保护的组件进行扩大的替换,目前因为Eureka、Zuul、Hystrix已不再开源,导致Spring开源基金会无奈收费获取其受权,从而进行更新和保护,阿里别离推出nacos、gateway、Sentinel来代替,并退出了Alibaba Cloud SchedulerX、Seata、Alibaba Cloud SMS等组件,性能更丰盛。

July 20, 2021 · 1 min · jiezi

关于spring-cloud:跟二师兄学Nacos吧EXT01篇-看看Nacos是怎么活学活用简单工厂模式的

学习不必那么功利,二师兄带你一起轻松读源码~番外篇简介Nacos源码剖析系列文章,在开篇曾经提到过,写作的指标有两个:第一,可能零碎的学习Nacos常识;第二,可能基于Nacos学到波及到的知识点或面。 为了不便大家学习,绝对应的文章题目会有所区别,Nacos原理局部命名依照失常编号进行。而番外篇,也就是技术点的解说则会在文章编号上增加“EXT-”的前缀。这样,如果大家只想学习Nacos原理常识,则可跳过EXT前缀的文章。 这篇文章咱们来看看Nacos Client中对工厂模式的应用。这里分两个步骤来理解,首先看看规范的工厂模式是什么样子的,而后再比照一下Nacos中的实现与规范实现有什么区别。 工厂模式概述在23种设计模式当中,工厂模式蕴含两种:工厂办法模式和形象工厂模式。它们都属于创立型模式,而还有一种简略工厂模式,尽管常常被用到,但可能是过于简略,未被纳入23种设计模式当中。 简略工厂模式上面先介绍一下,简略工厂模式,并对Nacos中的应用进行比照,并思考为什么会这样设计。 简略工厂模式简介简略工厂模式,又叫做动态工厂办法(Static Factory Method)模式。简略工厂模式是由一个工厂对象依据不同的参数类型返回不同实例。简略工厂模式是工厂模式家族中最简略实用的模式,能够了解为是不同工厂模式的一个非凡实现。 对于简略工厂模式,要解决的问题便是封装实例创立的过程。须要什么类,只需传入一个对应的参数,就能够取得所需的对象,调用者无需晓得实例的创立过程。被创立的实例通常都具备独特的父类。 简略工厂模式的构造UML图展现如下: 简略工厂通常包含三局部: Factory(工厂):外围局部,负责实现创立所有产品的外部逻辑,工厂类能够被外界间接调用,创立所需对象;AbstractProduct(形象产品类):工厂类所创立的所有对象的父类,封装了产品对象的公共办法,所有的具体产品为其子类对象;ConcreteProduct(具体产品):简略工厂模式的创立指标,实现了形象产品类,所有被创立的对象都是某个具体类的实例;其中形象产品类能够是接口,也能够说抽象类。 简略工厂模式的实现这里假如Nacos的配置核心服务和命名服务都继承自对立的NacosService,同时都须要提供一个注册办法。 形象产品类定义如下: public interface NacosService { /** * 注册实例信息 * @param object 实例信息,这里用Object代替 */ void register(Object object);}命名服务NamingService的具体实现: public class NamingService implements NacosService { @Override public void register(Object object) { System.out.println("注册命名服务胜利"); }}配置服务ConfigService的具体实现: public class ConfigService implements NacosService { @Override public void register(Object object) { System.out.println("配置核心实例注册胜利"); }}提供一个工厂类NacosFactory: public class NacosFactory { public static NacosService getService(String name) { if ("naming".equals(name)) { return new NamingService(); } else { return new ConfigService(); } }}其中依据传入的参数,生成不同类型的NacosService具体实现。 ...

July 19, 2021 · 1 min · jiezi

关于spring-cloud:使用DebeziumPostgres和Kafka进行数据实时采集CDC

1. 背景始终在欠缺本人的微服务架构,其中蕴含分布式工作流服务的建设,目前采纳的是Camunda工作流引擎。应用Camunda工作流,就会波及到工作流引擎的用户体系如何与现有用户体系集成的问题(Flowable、Activity也相似)。现有设计中,工作流定位偏重于企业外部流程的流转,因而零碎中设计了单位、部门、人员以及人事归属与Camunda工作流用户体系对应。 功能设计实现,就面临另外一个问题,如何解决现有人事体系数据如何【实时】同步至Camunda工作流引擎中。如果现有体系数据与工作流数据在同一个库中,绝对比拟好解决。而微服务架构中,不同服务的数据通常寄存在不同数据库中,那么就须要进行数据的同步。采纳的形式不同,能够获得的成果也雷同。 最后思考如下两种计划,然而都略感有余: ETL:应用ETL工具进行数据同步是典型的形式,能够抉择工具也比拟多。开源的ETL工具增量同步问题解决的并不现实,不应用增量同步数那么数据同步始终存在时间差;商业的ETL工具增量同步解决的比拟好,然而宏大且低廉。音讯队列:音讯队列是多系统集成广泛采纳的形式,能够很好的解决数据同步的实时问题。然而数据同步的两端都须要本人编写代码,一端写生产代码一端写生产代码,生产端代码还要捆绑现有体系数据所有操作,须要的编写量比拟大。查问比照的大量的材料,最终抉择了Debezimu来解决以上问题以及将来更多数据同步的问题。 2. Debezium介绍RedHat开源的Debezium是一个将多种数据源实时变更数据捕捉,造成数据流输入的开源工具。它是一种CDC(Change Data Capture)工具,工作原理相似大家所熟知的Canal, DataBus, Maxwell等,是通过抽取数据库日志来获取变更的。官网介绍为: Debezium is an open source distributed platform for change data capture. Start it up, point it at your databases, and your apps can start responding to all of the inserts, updates, and deletes that other apps commit to your databases. Debezium is durable and fast, so your apps can respond quickly and never miss an event, even when things go wrongDebezium是一个分布式平台,它将您现有的数据库转换为事件流,因而应用程序能够看到数据库中的每一个行级更改并立刻做出响应。Debezium构建在Apache Kafka之上,并提供Kafka连贯兼容的连接器来监督特定的数据库管理系统。 ...

July 18, 2021 · 5 min · jiezi

关于springcloud:聊聊如何根据环境动态指定feign调用服务名

前言前段时间和敌人聊天,他说他部门老大给他提了一个需要,这个需要的背景是这样,他们开发环境和测试环境共用一套eureka,服务提供方的serviceId加环境后缀作为辨别,比方用户服务其开发环境serviceId为user_dev,测试环境为user_test。每次服务提供方公布的时候,会依据环境变量,主动变更serviceId。 生产方feign调用时,间接通过 @FeignClient(name = "user_dev")来进行调用,因为他们是间接把feignClient的name间接写死在代码里,导致他们每次发版到测试环境时,要手动改name,比方把user_dev改成user_test,这种改法在服务比拟少的状况下,还能够承受,一旦服务一多,就容易改漏,导致原本该调用测试环境的服务提供方,后果跑去调用开发环境的提供方。 他们的老大给他提的需要是,生产端调用须要主动依据环境调用到相应环境的服务提供方。 上面就介绍敌人通过百度搜寻进去的几种计划,以及前面我帮敌人实现的另一种计划 计划一:通过feign拦截器+url革新1、在API的URI上做一下非凡标记@FeignClient(name = "feign-provider")public interface FooFeignClient { @GetMapping(value = "//feign-provider-$env/foo/{username}") String foo(@PathVariable("username") String username);}这边指定的URI有两点须要留神的中央 一是后面“//”,这个是因为feigntemplate不容许URI有“http://"结尾,所以咱们用“//”标记为前面紧跟着服务名称,而不是一般的URI二是“$env”,这个是前面要替换成具体的环境2、在RequestInterceptor中查找到非凡的变量标记,把$env替换成具体环境@Configurationpublic class InterceptorConfig { @Autowired private Environment environment; @Bean public RequestInterceptor cloudContextInterceptor() { return new RequestInterceptor() { @Override public void apply(RequestTemplate template) { String url = template.url(); if (url.contains("$env")) { url = url.replace("$env", route(template)); System.out.println(url); template.uri(url); } if (url.startsWith("//")) { url = "http:" + url; template.target(url); template.uri(""); } } private CharSequence route(RequestTemplate template) { // TODO 你的路由算法在这里 return environment.getProperty("feign.env"); } }; }}这种计划是能够实现,然而敌人没有驳回,因为敌人的我的项目曾经是上线的我的项目,通过革新url,老本比拟大。就放弃了 ...

July 15, 2021 · 3 min · jiezi

关于springcloud:吃透微服务-服务追踪之Sleuth

大家好,我是小菜。 一个心愿可能成为 吹着牛X谈架构 的男人!如果你也想成为我想成为的人,不然点个关注做个伴,让小菜不再孤独! 本文次要介绍 SpringCloud之服务网关Gateway 如有须要,能够参考 如有帮忙,不忘 点赞 ❥ 微信公众号已开启,小菜良记,没关注的同学们记得关注哦! 前段时间与小伙伴闲聊时说到他们公司的现状,近来与未来,公司将全面把单体服务向微服务架构过渡。这外面咱们听到了关键词 --- 微服务。乍听之下,感觉也很正当。互联网在一直的倒退,这里不只是行业的倒退,更是零碎架构的倒退。当初市面上架构大抵也经验了这几个阶段: 这是坏事吗?是坏事,毋庸置疑。因为不跟上时代的浪潮,总会被拍死在沙滩上。但齐全是坏事吗?那也不见得。 咱们先要明确微服务解决了什么问题?大方面上应该就是利用层面和人层面的问题 利用层面: 单体服务的架构很简略,我的项目开发和保护成本低是它无争议的长处。然而臃肿耦合又会给基础设施带来了过重的累赘。如果某个利用解决资源占用了大量的CPU,就会导致其余解决资源饿死的景象,零碎提早增高,间接影响零碎的可用性。人层面: 独立、多语言生态 也是微服务的标签。在单体服务中,投入的人力资源越多不见得越高效,反而越容易出错。但微服务不同,每个服务都是独立进去的,团队能够更加容易的合作开发,甚至一套零碎,多个服务,多种语言,毫无抵触。 然而咱们凡事不能被益处蒙蔽。微服务的毛病也是始终存在的: 须要思考各个服务之间的容错性问题须要思考数据一致性问题须要思考分布式事务问题...很多人认为微服务的外围就是在于 微。服务分的越细越好,就如同平时写代码的时候丝毫不思考的繁多准则,反而在服务拆分上用到酣畅淋漓。这里就须要明确一个外围概念:微服务的要害不在微,而是在于适合的大小 这句话如同很简略的样子,然而多大才算适合的大小?这可能据不同团队,不同我的项目而定。适合的大小可能取决于更少的代码仓库,更少的部署队列,更少的语言... 这里更无奈一锤定音! 如果没法做到适合的大小,而无脑的拆分服务,那么微服务可能反而成为你我的项目的累赘。因而,有时全面转型微服务反而不是坏事,你感觉呢? 话题有点跑远了,咱们致力扯回来。既然微服务曾经成为支流,那么如何设计微服务便是咱们应该做的事,而不是谈及微服务之时,想到的只是与人如何争执如何拒用微服务。那么这篇咱们要讲的是SpringCloud之服务网关Gateway SpringCloud之服务网关Gateway一、意识网关什么是服务网关?不要给本人当头一棒。咱们换个问法,为什么须要服务网关? 服务网关是跨一个或多个服务节点提供单个对立的拜访入口它的作用并不是可有可无的存在,而是至关重要。咱们能够在服务网关做路由转发和过滤器的实现。长处简述如下: 避免外部服务关注裸露给内部客户端为咱们外部多个服务增加了额定的平安层减低微服务拜访的复杂性 依据图中内容,咱们能够得出以下信息: 用户拜访入口,对立通过网关拜访到其余微服务节点服务网关的性能有路由转发,API监控、权限管制、限流而这些便是 服务网关 存在的意义! 1)Zuul 比拟SpringCloud Gateway 是 SpringCloud 的一个全新我的项目,指标是取代Netflix Zuul。它是基于 Spring5.0 + SpringBoot2.0 + WebFlux 等技术开发的,性能高于 Zuul,据官网提供的信息来看,性能是 Zuul 的1.6倍,意在为微服务架构提供一种简略无效的对立的 API 路由治理形式。 SpringCloud Gateway 不仅提供了对立的路由形式(反向代理),并且基于 Filter 链(定义过滤器对申请过滤)提供了网关根本的性能,例如:鉴权、流量管制、熔断、门路重写、日志监控等。 其实说到 Netflix Zuul,在应用或筹备应用微服务架构的小伙伴应该并不生疏,毕竟Netflix 是一个老牌微服务开源者。新秀与老牌之间的抢夺,如果新秀没有点硬实力,如何让人安心转型! 这里咱们能够顺带理解一下 Weflux,Webflux 的呈现填补了 Spring 在响应式编程上的空白。 可能有很多小伙伴并不知道 Webflux,小菜接下来也会出一篇对于 Webflux 的解说,实则真香!Webflux 的响应式编程不仅仅是编程格调上的扭转,而是对于一系列驰名的框架都提供了响应式拜访的开发包,比方 Netty、Redis(如果不晓得 Netty 的实力,能够想想为什么 Nginx 能够承载那么大的并发,底层就是基于Netty) ...

July 12, 2021 · 3 min · jiezi

关于spring-cloud:Spring-Cloud-Netflix整合Eureka

Spring-Cloud Euraka是Spring Cloud汇合中一个组件,它是对Euraka的集成,用于服务注册和发现。Eureka是Netflix中的一个开源框架。它和 zookeeper、Consul一样,都是用于服务注册治理的,同样,Spring-Cloud 还集成了Zookeeper和Consul。 搭建eureka服务注册核心引入以下依赖<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <!-- 最新版的 eureka 服务端包 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> </dependencies> <!-- SpringCloud依赖,起到治理版本的作用 --> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Hoxton.SR9</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>Spring Cloud 和 Spring Boot 之间版本对应关系Release TrainBoot Version2020.0.x aka Ilford2.4.xHoxton2.2.x, 2.3.x (Starting with SR5)Greenwich2.1.xFinchley2.0.xEdgware1.5.xDalston1.5.x在启动类上增加@EnableEurekaServer注解,表明这是一个Eureka服务端@SpringBootApplication@EnableEurekaServerpublic class SpringCloudEurekaApplication { public static void main(String[] args) { SpringApplication.run(SpringCloudEurekaApplication.class, args); }}在application.properties中增加一些配置server.port=8080spring.application.name=Eureka-Server# 指定了Eureka服务端的IPeureka.instance.hostname=localhosteureka.instance.statusPageUrl=http://${eureka.instance.hostname}:${server.port}/infoeureka.instance.healthCheckUrl=http://${eureka.instance.hostname}:${server.port}/healtheureka.instance.homePageUrl=http://${eureka.instance.hostname}/# 示意是否将服务注册到Eureka服务端,因为本身就是Eureka服务端,所以设置为false# eureka.client.register-with-eureka=false# 示意是否从Eureka服务端获取服务信息,因为这里只搭建了一个Eureka服务端,并不需要从别的Eureka服务端同步服务信息,所以这里设置为false# eureka.client.fetch-registry=false# 指定Eureka服务端的地址,默认值为http://localhost:8761/eureka 指定Eureka服务端的地址为另外一个Eureka服务端的地址8081eureka.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/# 用于定义服务续约工作的调用间隔时间,默认30秒eureka.client.serviceUrl.registry-fetch-interval-seconds=5配置结束后启动服务,拜访http://localhost:8080/ 因为还没有Eureka客户端将服务注册进来,所以Instances currently registered with Eureka列表是空的 ...

June 29, 2021 · 2 min · jiezi

关于springcloud:吃透微服务-服务容错之Sentinel

大家好,我是小菜。一个心愿可能成为 吹着牛X谈架构 的男人!如果你也想成为我想成为的人,不然点个关注做个伴,让小菜不再孤独! 本文次要介绍 SpringCloud中Sentinel 如有须要,能够参考 如有帮忙,不忘 点赞 ❥ 微信公众号已开启,小菜良记,没关注的同学们记得关注哦! 上篇咱们曾经理解到微服务中重要的组件之一 --- 服务网关Gateway 。咱们在取精排糠的同时,不可否认微服务给咱们带来的益处。其中承载高并发的益处更是让各大公司趋之若鹜! 然而想要接管高并发,天然要接管它带来的一系列问题。在微服务架构中,咱们将业务拆分成了一个个服务,这样的益处之一便是分担压力,一个服务顶不住了,下一个服务顶上去。然而服务与服务之间能够互相调用,因为网络起因或本身的起因,服务并不能保障百分百可用,也就是各大公司当初追寻的几个9(99.99%,99.999%)可用!如果单个服务呈现问题,调用这个服务就会呈现网络提早,此时如果正好有大量的网络涌入,势必会造成工作沉积,导致服务瘫痪! 空口无凭,小菜给你整个示例: OrderController 这里咱们通过接口模仿了下单的场景,其中通过线程休眠的形式模仿了网络提早的场景。接下来咱们还须要改一下 tomcat 中并发的线程数 applicatio.yaml server: tomcat: max-threads: 10 # 默认的并发数为200当这所有准备就绪好,咱们这个时候还须要压测工具 Jmeter 的帮忙(不会操作的同学具体看以下应用) 首先关上Jmeter软件,抉择新建线程组 设置申请线程数 设置HTTP申请取样器 设置申请的接口 实现下面步骤就能够点击开始了。不过测试之前咱们确保两个API都是能够拜访的: 而后开始压力测试,当大量申请发送到创立订单的接口时,咱们这时候通过网页拜访 detail API 发现申请始终在阻塞,过一会才联通! 这无疑是一个开发炸弹,而这便是高并发带来的问题。看到这里,祝贺你胜利见证了一场服务雪崩的问题。那无妨带着这份趣味持续往下看,会给你惊喜的。 Sentinel一、服务雪崩咱们结尾间接用服务雪崩勾引你,不晓得你心动了没有,如果不想你的我的项目在线上环境面临同样的问题,连忙为我的项目搭线起来,不经意的行动往往能让你升职加薪! 在分布式系统中,因为网络起因或本身的起因。服务个别无奈保障 100% 可用,如果一个服务呈现了问题,调用这个服务就会呈现线程阻塞的状况,此时若有大量的申请涌入,就会呈现多条线程阻塞期待,进而导致服务瘫痪。而因为服务与服务之间的依赖性,故障会进行流传,相互影响之下,会对整个微服务零碎造成灾难性的严重后果,这就是服务故障的 “雪崩效应”! 最开始的时候,服务A~C 三个服务其乐融融的互相调用,响应也很快,为主人工作也很卖命 好景不长,客人火了,并发量上来了。可能因为服务C还不够强壮的起因,服务C在某一天宕机了,然而服务B还是依赖服务C,不停的进行服务调用 这个时候可能大家都还没意识到问题的严重性,只是狐疑可能申请太多了,导致服务器变卡了。申请持续发送,服务A这个时候也未知问题,一边感觉奇怪服务B是不是偷懒了,怎么还不把响应返回给它,一边持续发送申请。然而这个时候申请都在服务B沉积着,终于有一天服务B也累出问题了 这个时候人们开始埋怨服务A了,却不晓得服务A底层原来还依赖服务B和服务C,而这时服务B和服务C都挂了。服务A这时才想通为什么服务B之前那么久没返回响应,原来服务B也依赖服务C啊!然而这个时候曾经晚了,申请一直接管,一直沉积,下场都是惊人的类似,也走向了宕机的后果。不过有一点不同的是,服务A宕机后须要承载了用户各种的骂声~ 可悲的故事警觉了咱们,微服务架构之间并没有那么牢靠。有时候真的是说挂就挂,起因各种各样,不合理的容量设计,高并发状况下某个办法响应变慢,亦或是某台机器的资源耗尽。咱们如果不采取措施,只能坐以待毙,一直的在重启服务器中循环。然而咱们可能无奈杜绝雪崩的源头,然而如果咱们在问题产生后做好容错的筹备,保障下一个服务产生问题,不会影响到其余服务的失常运行,各个服务自扫家门雪,做到独立,雪落而不雪崩! 二、容错计划想要避免雪崩的扩散,就要做好服务的容错,容错说白了就是爱护本人不被其余队友坑,带进送人头的行列!那咱们有哪些容错的思路呢? 1)隔离计划它是指将零碎依照肯定的准则划分为若干个服务模块,各个模块之间互相独立,无强依赖。当有故障产生时,能将问题和影响隔离在某个模块外部,而不扩散危险,不波及其余模块,不影响整体的零碎服务。常见的隔离形式有:线程隔离 和信号量隔离: 2)超时计划在上游服务调用上游服务的时候,设置一个最大响应工夫,如果超过这个工夫上游服务还没响应,那么就断开连接,开释掉线程 3)限流计划限流就是限度零碎的输出和输入流量已达到爱护零碎的目标。为了保证系统的巩固运行,一旦达到须要限度的阈值,就须要限度流量并采纳大量措施实现限度流量的目标 限流策略有很多,前期也会思考出一篇专门将如何进行限流4)熔断计划在互联网零碎中,当上游服务因拜访压力过大而相应变慢或失败的时候,上游服务为了爱护零碎整体的可用性,能够临时切断对上游服务的调用。这种就义部分,顾全整体的措施就叫做熔断 其中熔断有分为三种状态: 熔断敞开状态(Closed)服务没有故障时,熔断器所处的状态,对调用方的调用不做任何限度 ...

June 28, 2021 · 4 min · jiezi

关于springcloud:使用Nacos注册和配置SpringCloud微服务

前言上篇咱们讲到如何应用k8s搭建nacos,这篇就来讲讲微服务如何通过搭建好的nacos服务注册和配置。 操作A服务、B服务,A应用Feign调用B服务外面办法。 A、B服务引入相干依赖包, springcloud版本:2020.0.0springboot版本:2.4.2alibaba版本:2021.1 <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.4.2</version></parent><properties> <java.version>1.8</java.version> <spring-boot.version>2.4.2</spring-boot.version> <spring-cloud.version>2020.0.0</spring-cloud.version> <spring-cloud-alibaba.version>2021.1</spring-cloud-alibaba.version></properties><dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> <!-- spring cloud 依赖 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> <!-- spring cloud alibaba 依赖 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>${spring-cloud-alibaba.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies></dependencyManagement><dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-loadbalancer</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bootstrap</artifactId> </dependency></dependencies>A、B服务注册和配置到Nacos服务的bootstrap.yml文件: spring:application: name: a-service # b-serviceprofiles: active: testcloud: nacos: #注册A、B服务到Nacos discovery: server-addr: http://nacos-headless.default.svc.cluster.local:8848 namespace: xxx-xxx-xxx-xxx service: a-service # b-service #配置A、B服务到Nacos config: server-addr: http://nacos-headless.default.svc.cluster.local:8848 file-extension: yaml prefix: a-service # b-service namespace: xxx-xxx-xxx-xxxserver:port: a-port # b-port能够间接在Nacos下面创立A、B服务的配置文件: ...

June 27, 2021 · 1 min · jiezi

关于springcloud:升级SpringCloudSpringBoot和Alibaba版本

前言始终在应用SpringCloud Hoxton.SR4版本,以及SpringBoot 2.2.5.RELEASE版本,自从SpringCloud降级到2020.0之后想尝试下降级,并且把遇到的问题记录下来分享给大家 版本对照官网有个SpringCloud和SpringBoot对照版本,我就是参考该版本来降级的。上面是通过Json形式展现SpringCloud版本对照 上面是Nacos对应SpringCloud和SpringBoot各版本对照表: 所以我选用的SpringCloud版本是2020.0.0,SpringBoot版本是2.4.2,Alibaba版本是2021.1,上面咱们就来降级。 开始降级引入相干依赖包 <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.4.2</version></parent><properties> <java.version>1.8</java.version> <spring-boot.version>2.4.2</spring-boot.version> <spring-cloud.version>2020.0.0</spring-cloud.version> <spring-cloud-alibaba.version>2021.1</spring-cloud-alibaba.version></properties><dependencyManagement> <dependencies> <!-- spring boot 依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> <!-- spring cloud 依赖 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> <!-- spring cloud alibaba 依赖 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>${spring-cloud-alibaba.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies></dependencyManagement><dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-oauth2</artifactId> <version>2.2.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-security</artifactId> <version>2.2.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-loadbalancer</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> <!-- 增加对bootstrap.yml反对 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bootstrap</artifactId> </dependency></dependencies>降级过程中遇到的问题1、有些依赖包版本要写死如:spring-cloud-starter-oauth2,是因为,cloud2020.0.0以上版本移除spring-cloud-security-dependencies依赖。2、pom引入spring-cloud-starter-bootstrap包,否则bootstrap.yml不起作用,3、nacos discovery要加service属性否则报错,如下所示:spring: application: name: aaa profiles: active: test cloud: nacos: discovery: server-addr: http://nacos-host:8848 namespace: xxx-xxx-xxx service: aaa config: server-addr: http://nacos-host:8848 file-extension: yaml prefix: aaa namespace: xxx-xxx-xxxserver: port: 8901总结1、之前版本的spring-cloud--starter-oauth2包没有了,没有找到对应的。援用包spring-security-oauth2和 spring-security-oauth2-autoconfigure也能实现 oauth2 server性能,但相干的类提醒过期。2、之前的版本当spring cloud bus和mq一起应用时,无奈应用stream3.0的写法来接管音讯,当初这个问题曾经解决。除了eureka,其它的netflix组件都曾经删除援用SpringCloud 降级到2020记录报错dependencies.dependency.version is missingSpring Cloud Alibaba降级到2.1.0 所遇到的坑nacos版本阐明springcloud版本对照 ...

June 27, 2021 · 1 min · jiezi

关于springcloud:SpringCloud之消息总线Bus

一、概述1、是什么Bus反对两种音讯代理RabbitMQ和Kafka,Bus配合Config应用实现配置的动静刷新。用来将分布式系统的节点与轻量级音讯零碎链接起来的框架,整合了Java的事件处理机制和消息中间件性能。 2、能干嘛Bus能治理和流传分布式系统间的音讯,就像一个分布式执行器,能够用于播送状态更改,事件推送等,也能够当做微服务间的通信通道。 3、总线是什么及基本原理是什么:在微服务架构的零碎中,通常会应用轻量级的音讯代理来构建一个共用的音讯主题,并让零碎中所有微服务实例都连贯上来,因为该主题中产生的音讯会被所有实例监听和生产,所以称之为音讯总线。基本原理:ConfigClient实例都监听MQ中同一个topic(默认就是Bus)当一个服务刷新数据,就会把这个音讯放入到topic中,这样其它监听同一个topic的服务就能失去告诉,而后更新本身配置。 二、Bus动静刷新全局播送必须先具备良好的MQ环境演示播送成果,减少复杂度。增加配置核心客户端B设计思路1)利用音讯总线触发一个客户端/bus/refresh,而刷新所有客户端的配置。2)利用音讯总线触发一个服务端ConfigServer的/bus/refresh端点,而刷新所有客户端配置。3)抉择第二种形式,起因:突破了微服务的职责单一性,微服务自身是业务模块,不应该承当配置刷新职责;毁坏了微服务各节点的对等性;有肯定局限性。配置核心服务端增加音讯总线反对1.pom增加bus-amqp的包依赖2.yml1)增加rabbitmq相干配置rabbitmq.host=地址rabbitmq.port=端口rabbitmq.username=用户名rabbitmq.password=明码2)裸露bus刷新配置的端点management.endpoints.web.exposure.include='bus-refresh'配置核心客户端A增加音讯总线反对1.pom增加bus-amqp的包依赖2.yml1)增加rabbitmq相干配置rabbitmq.host=地址rabbitmq.port=端口rabbitmq.username=用户名rabbitmq.password=明码2)裸露bus刷新配置的端点management.endpoints.web.exposure.include='*'配置核心客户端B增加音讯总线反对(同客户端A)批改github上配置文件,发送post申请,发现客户端都曾经刷新,一次批改播送告诉,处处失效。POST申请:curl -x POST "服务器地址/actuator/bus-refresh" 三、Bus动静刷新定点告诉不想全副告诉,只想定点告诉。指定具体某一个实例失效而不是全副;公式:http://localhost:3344/actuator/bus-refresh/{destination};/bus/refresh申请不再发送到具体的服务实例上,而是发给config server,通过destination参数指定须要更新配置的服务或实例(服务名+端口号)。

June 25, 2021 · 1 min · jiezi

关于springcloud:SpringBoot应用整合ELK实现日志收集

摘要内容

June 24, 2021 · 1 min · jiezi

关于springcloud:SpringCloud入门7Bus

上一节中的Config尽管解决了配置文件繁冗的问题,然而有一个弊病,那就是当咱们服务端代码批改后,也就是gitee上的货色批改后须要再次启动服务才可能使批改失效。 为了解决这个问题,SpringCloud推出了Bus,学过计网的同学有印象就会晓得总线这个货色,就相似播送一样,本篇文章也是SpringCloud入门系列的终章。 引入Bus建设一个空父bus模块,批改父模块的pom文件,导入对应的依赖以供其子模块应用。 <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency></dependencies>看到spring-cloud-starter-bus-amqp 就晓得须要rabbitmq,在练手的状况个别我都利用wsl2应用docker,下载rabbitmq镜像并且开启,大家能够各显神通,反正能下载就行了。 判断是否下载胜利只须要拜访http://localhost:15672 ,呈现以下界面就是胜利 用户名和明码都是guest,登录进去后能看到以下界面 在bus父模块下首先建设一个bus-config-client9601 子模块。 配置文件从服务端获取内容,所以得设置服务端的相干内容,也就是spring.cloud.config.xxx ,还须要设置bus,rabbitmq,actuator,eureka等相干内容,最终的配置文件如下: server.port: 9601spring: application: name: bus-config-client cloud: config: profile: dev label: master uri: http://localhost:8101 #服务端地址 bus: #开启bus enabled: true trace: enabled: true rabbitmq: #设置rabbitmq的相干信息 host: localhost port: 5672 username: guest password: guestmanagement: #开启actuator endpoints: web: exposure: include: bus-refresh #开启主动刷新的apieureka: #惯例设置eureka client: fetch-registry: true register-with-eureka: true service-url: defaultZone: http://localhost:8001/eureka/ instance: instance-id: bus-config-client9601除此之外的配置文件都是通过conifg从服务端中间接获取 ...

June 17, 2021 · 1 min · jiezi

关于springcloud:面试中你有遇到这些Spring-Cloud常问题吗知道如何完美解答吗

为什么须要学习Spring Cloud不论是商业利用还是用户利用,在业务初期都很简略,咱们通常会把它实现为单体构造的利用。然而,随着业务逐步倒退,产品思维会变得越来越简单,单体构造的利用也会越来越简单。这就会给利用带来如下的几个问题: 代码构造凌乱:业务简单,导致代码量很大,治理会越来越艰难。同时,这也会给业务的疾速迭代带来微小挑战;开发效率变低:开发人员同时开发一套代码,很难防止代码抵触。开发过程会随同着一直解决抵触的过程,这会重大的影响开发效率;排查解决问题老本高:线上业务发现 bug,修复 bug 的过程可能很简略。然而,因为只有一套代码,须要从新编译、打包、上线,老本很高。因为单体构造的利用随着零碎复杂度的增高,会暴露出各种各样的问题。近些年来,微服务架构逐步取代了单体架构,且这种趋势将会越来越风行。Spring Cloud是目前最罕用的微服务开发框架,曾经在企业级开发中大量的利用。 什么是Spring CloudSpring Cloud是一系列框架的有序汇合。它利用Spring Boot的开发便利性奇妙地简化了分布式系统基础设施的开发,如服务发现注册、配置核心、智能路由、音讯总线、负载平衡、断路器、数据监控等,都能够用Spring Boot的开发格调做到一键启动和部署。 Spring Cloud并没有反复制作轮子,它只是将各家公司开发的比拟成熟、经得起理论考验的服务框架组合起来,通过Spring Boot格调进行再封装屏蔽掉了简单的配置和实现原理,最终给开发者留出了一套简略易懂、易部署和易保护的分布式系统开发工具包。 设计指标与优缺点设计指标 协调各个微服务,简化分布式系统开发。 优缺点 微服务的框架那么多比方:dubbo、Kubernetes,为什么就要应用Spring Cloud的呢? 长处: 产出于Spring大家族,Spring在企业级开发框架中无人能敌,来头很大,能够保障后续的更新、欠缺组件丰盛,功能齐全。Spring Cloud 为微服务架构提供了十分残缺的反对。例如、配置管理、服务发现、断路器、微服务网关等;Spring Cloud 社区活跃度很高,教程很丰盛,遇到问题很容易找到解决方案服务拆分粒度更细,耦合度比拟低,有利于资源重复利用,有利于进步开发效率能够更精准的制订优化服务计划,进步零碎的可维护性加重团队的老本,能够并行开发,不必关注其他人怎么开发,先关注本人的开发微服务能够是跨平台的,能够用任何一种语言开发适于互联网时代,产品迭代周期更短毛病: 微服务过多,治理老本高,不利于保护零碎分布式系统开发的老本高(容错,分布式事务等)对团队挑战大总的来说长处大过于毛病,目前看来Spring Cloud是一套十分欠缺的分布式框架,目前很多企业开始用微服务、Spring Cloud的劣势是不言而喻的。因而对于想钻研微服务架构的同学来说,学习Spring Cloud是一个不错的抉择。 Spring Cloud发展前景Spring Cloud对于中小型互联网公司来说是一种福音,因为这类公司往往没有实力或者没有足够的资金投入去开发本人的分布式系统基础设施,应用Spring Cloud一站式解决方案能在从容应对业务倒退的同时大大减少开发成本。 同时,随着近几年微服务架构和Docker容器概念的火爆,也会让Spring Cloud在将来越来越“云”化的软件开发格调中立有一席之地,尤其是在形形色色的分布式解决方案中提供了标准化的、全站式的技术计划,意义可能会堪比当年Servlet标准的诞生,无效推动服务端软件系统技术水平的提高。 整体架构 次要我的项目Spring Cloud的子项目,大抵可分成两类,一类是对现有成熟框架"Spring Boot化"的封装和形象,也是数量最多的我的项目;第二类是开发了一部分分布式系统的基础设施的实现,如Spring Cloud Stream表演的就是kafka, ActiveMQ这样的角色。 Spring Cloud Config 集中配置管理工具,分布式系统中对立的内部配置管理,默认应用Git来存储配置,能够反对客户端配置的刷新及加密、解密操作。 Spring Cloud Netflix Netflix OSS 开源组件集成,包含Eureka、Hystrix、Ribbon、Feign、Zuul等外围组件。 Eureka:服务治理组件,包含服务端的注册核心和客户端的服务发现机制;Ribbon:负载平衡的服务调用组件,具备多种负载平衡调用策略;Hystrix:服务容错组件,实现了断路器模式,为依赖服务的出错和提早提供了容错能力;Feign:基于Ribbon和Hystrix的申明式服务调用组件;Zuul:API网关组件,对申请提供路由及过滤性能。Spring Cloud Bus 用于流传集群状态变动的音讯总线,应用轻量级音讯代理链接分布式系统中的节点,能够用来动静刷新集群中的服务配置。 Spring Cloud Consul 基于Hashicorp Consul的服务治理组件。 Spring Cloud Security 平安工具包,对Zuul代理中的负载平衡OAuth2客户端及登录认证进行反对。 Spring Cloud Sleuth ...

June 15, 2021 · 2 min · jiezi

关于springcloud:SpringCloud入门5Zuul

网上很多资源都把API网关,是什么,能做什么解释得十分分明,然而对于初学者来说我感觉是不够敌对的,Zuul就是SpringCloud微服务中的网关。 对于初学者入门来说,只须要晓得Zuul就是当服务增多之后,就要对API进行一个对立的治理,某个类型的API就会调用某个类型的服务,除此之外还能对申请过去的API进行一个过滤。更进一步才是Zuul其它作用,具体有哪些作用如图所示: 本文重点解说的是路由转发 和过滤器 。 1 如何引入Zuul一样的,建设一个Zuul模块,本例中没有什么生产端,所以就没有采取之前建设空父模块再建设具体子模块的办法。而后往Zuul中的pom文件中增加依赖: <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-zuul</artifactId> </dependency></dependencies>到当初整个我的项目的目录构造如图所示: 2 主启动类和配置文件因为不波及服务生产等,只是做api的解决,所以主启动类还是比较简单的 @SpringBootApplication@EnableZuulProxy //开启Zuul@EnableEurekaClientpublic class ZuulMain9401 { public static void main(String[] args) { SpringApplication.run(ZuulMain9401.class, args); }}配置文件的话和惯例的Eureka客户端是一样的 spring: application: name: zuul9401server: port: 9401eureka: client: fetch-registry: true register-with-eureka: true service-url: defaultZone: http://localhost:8001/eureka/ instance: instance-id: zuul94013 路由转发路由转发次要是通过配置文件来批改,往上面配置文件中减少内容 ,上面会讲3种形式的转发路由。 设置注册Eureka的服务id减少第一波配置文件,是在原有的配置文件上减少了以下内容。 zuul: routes: user-a: path: /api-a/** serviceId: eureka-provideuser-a 是轻易定义 ,path 是内部拜访的门路,serviceId是微服务配置文件的spring.application.name 的值。 所以下面减少的配置文件整体意思是,当内部拜访/api-a/ 相干门路时候,会转发给名字为eureka-provid 的服务提供服务。 开启Eureka服务注册核心EurekaServer8001 ,服务提供者EurekaProvide7001/2/3 ,API网关ZuulMain9401 : 接着拜访http://localhost:9401/api-a/e...eureka-provide 服务里的eureka/provide门路。 ...

June 8, 2021 · 3 min · jiezi

关于springcloud:SpringCloud入门4Hystrix

通过前3节的SpringCloud学习,理解了服务的提供者可能不止有一个端口,在当前的真正的工作中可能还不止有一个微服务来提供服务。如果服务崩掉,如果没有措施,会导致很重大的损失。 就比方如果提供的是购物服务,总不可能让顾客买货色。还有生存中最常见的例子是当家庭某个电器短路的时候,为了保障整体电器,保险丝就会进行熔断。 Hystrix的诞生就是为了解决这个问题。 1 引入Hystrix建设hystrix父模块,批改父模块pom文件使其子模块都导入了依赖,不便当前操作。 <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency></dependencies>随后在父模块下新建一个hystrix-consume9301 子模块,最初的我的项目构造目录如下: 2 主启动类和配置文件配置文件: spring: application: name: hystrix-consume9301server: port: 9301eureka: client: fetch-registry: true register-with-eureka: true service-url: defaultZone: http://localhost:8001/eureka/ instance: instance-id: hystrix-consume9301其实配置文件简略来说都是一样的,始终反复写进去就是为了大家不便cv复现 主启动类: @SpringBootApplication@EnableEurekaClient@EnableHystrix //开启Hystrix@RestController //开启业务类public class HystrixConsume9301 { public static void main(String[] args) { SpringApplication.run(HystrixConsume9301.class, args); }}3 业务类再次强调是为了不便入门,间接在主启动类中编写业务类,这是不标准的。 为了可能进行服务间的调用,在入门Eureka的时候也说到了利用RestTemplate 即可,所以须要增加一个config类把RestTemplate 注入到Spring容器中。 @Configurationpublic class ApplicationContextConfig { @Bean @LoadBalanced //开启负载平衡性能,加了此注解能力通过服务名来拜访服务 public RestTemplate getRestTemplate() { return new RestTemplate(); }}回过来看主启动类 @SpringBootApplication@EnableEurekaClient@EnableHystrix //开启Hystrix@RestController //开启业务类public class HystrixConsume9301 { public static void main(String[] args) { SpringApplication.run(HystrixConsume9301.class, args); } //服务名字 final String PROVIDE_URL = "http://eureka-provide"; RestTemplate restTemplate; public HystrixConsume9301(RestTemplate restTemplate) { this.restTemplate = restTemplate; } @GetMapping("/hystrix/consume") @HystrixCommand(fallbackMethod = "getInfoFallback") //开启降级服务 public String getInfo() { return "i am hystrix consumer, but actually invoke provide service: [" + restTemplate.getForObject(PROVIDE_URL + "/eureka/provide", String.class) + "]"; } public String getInfoFallback() { return "hello, something wrong, i am getInfo fallback method"; }}其它所有都一样,只不过是在相应的业务办法中增加了@HystrixCommand 注解,该注解中的fallbackMethod 申明的是服务降级后回调的是哪个办法。 ...

June 3, 2021 · 2 min · jiezi

关于springcloud:SpringCloud入门3OpenFeign

Feign的目标是为了编写Java客户端变得更加容易,大白话就是能够让咱们像平时controller调service一样不便,没有前两篇文章那么繁琐,具体能够看上面的例子。 1 引入OpenFeign建设一个父open-feign模块,在其模块下再建设一个子feign-server模块,为了导入OpenFeign模块,须要批改父模块的pom文件,其实就是退出了依赖 <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId></dependency>这样就可能把OpenFeign引入,最终的我的项目构造如下 2 配置文件和主启动类没有什么非凡状况,服务都是注册进Eureka中,而后再编写本人的端口和服务名称即可。 eureka: client: service-url: defaultZone: http://localhost:8001/eureka/server: port: 8101spring: application: name: feign-server@SpringBootApplication@EnableEurekaClient@EnableDiscoveryClient//@EnableFeignClients //留神这个正文掉的注解public class FeignConusme9201 { public static void main(String[] args) { SpringApplication.run(FeignConusme9201.class, args); }}这里简略说下@EnableDiscoveryClient 和@EnableEurekaClient 两个注解的区别,因为服务发现个别会有Eureka、Consul和Zookeeper三种实现。如果应用Eureka做服务注册和服务发现核心,举荐用后者;如果是其它注册核心,那么就能够用前者。 3 业务类service @FeignClient(value = "eureka-provide")public interface FeignService { @GetMapping(value = "/eureka/provide") String consume();}@GetMapping 中的值就是申请服务的地址,@FeignClient 注解外面的value同样也是name,还是反复同样一句话,这个值就是须要调用的服务端的配置文件中的springcloud.application.name 的值 ,对于@FeignClient 注解,大略有以下几个属性,大部分都能够顾名思义,当前可能会具体介绍。 controller @RestControllerpublic class FeignController { FeignService feignService; public FeignController(FeignService feignService) { this.feignService = feignService; } @GetMapping(value = "/feign/consume") public String consume() { return feignService.consume(); }}间接就很简略,和之前写的一般我的项目一样,相比之前少写了注入RestTemplate ,而后调用网址返回后果等。 ...

June 1, 2021 · 1 min · jiezi

关于spring-cloud:Spring-Cloud-升级之路20200x-7使用-Spring-Cloud-LoadBalancer-2

本我的项目代码地址:https://github.com/HashZhang/...咱们应用 Spring Cloud 官网举荐的 Spring Cloud LoadBalancer 作为咱们的客户端负载均衡器。上一节咱们理解了 Spring Cloud LoadBalancer 的构造,接下来咱们来说一下咱们在应用 Spring Cloud LoadBalancer 要实现的性能: 咱们要实现不同集群之间不相互调用,通过实例的metamap中的zone配置,来辨别不同集群的实例。只有实例的metamap中的zone配置一样的实例能力相互调用。这个通过实现自定义的 ServiceInstanceListSupplier 即可实现负载平衡的轮询算法,须要申请与申请之间隔离,不能共用同一个 position 导致某个申请失败之后的重试还是原来失败的实例。上一节看到的默认的 RoundRobinLoadBalancer 是所有线程共用同一个原子变量 position 每次申请原子加 1。在这种状况下会有问题:假如有微服务 A 有两个实例:实例 1 和实例 2。申请 A 达到时,RoundRobinLoadBalancer 返回实例 1,这时有申请 B 达到,RoundRobinLoadBalancer 返回实例 2。而后如果申请 A 失败重试,RoundRobinLoadBalancer 又返回了实例 1。这不是咱们冀望看到的。针对这两个性能,咱们别离编写本人的实现。 实现不同集群不相互调用Spring Cloud LoadBalancer 中的 zone 配置Spring Cloud LoadBalancer 定义了 LoadBalancerZoneConfig: public class LoadBalancerZoneConfig { //标识以后负载均衡器处于哪一个 zone private String zone; public LoadBalancerZoneConfig(String zone) { this.zone = zone; } public String getZone() { return zone; } public void setZone(String zone) { this.zone = zone; }}如果没有引入 Eureka 相干依赖,则这个 zone 通过 spring.cloud.loadbalancer.zone 配置:LoadBalancerAutoConfiguration ...

May 29, 2021 · 5 min · jiezi

关于springcloud:Spring-Cloud-升级之路-20200x-6-使用-Spring-Cloud-LoadBalancer1

本我的项目代码地址:https://github.com/HashZhang/...咱们应用 Spring Cloud 官网举荐的 Spring Cloud LoadBalancer 作为咱们的客户端负载均衡器。 Spring Cloud LoadBalancer背景Spring Cloud LoadBalancer是一个客户端负载均衡器,相似于Ribbon,然而因为Ribbon曾经进入保护模式,并且Ribbon 2并不与Ribbon 1互相兼容,所以Spring Cloud全家桶在Spring Cloud Commons我的项目中,增加了Spring cloud Loadbalancer作为新的负载均衡器,并且做了向前兼容,就算你的我的项目中持续用 Spring Cloud Netflix 套装(包含Ribbon,Eureka,Zuul,Hystrix等等)让你的我的项目中有这些依赖,你也能够通过简略的配置,把ribbon替换成Spring Cloud LoadBalancer。 负载均衡器在哪里应用?Spring Cloud 中外部微服务调用默认是 http 申请,次要通过上面三种 API: RestTemplate:同步 http APIWebClient:异步响应式 http API三方客户端封装,例如 openfeign如果我的项目中退出了 spring-cloud-loadbalancer 的依赖并且配置启用了,那么会主动在相干的 Bean 中退出负载均衡器的个性。 对于 RestTemplate,会主动对所有 @LoadBalanced 注解润饰的 RestTemplate Bean 减少 Interceptor 从而加上了负载均衡器的个性。对于 WebClient,会主动创立 ReactorLoadBalancerExchangeFilterFunction,咱们能够通过退出ReactorLoadBalancerExchangeFilterFunction会退出负载均衡器的个性。对于三方客户端,个别不须要咱们额定配置什么。这些应用的示例,会在咱们系列降级完最初的测试局部看到。 Spring Cloud LoadBalancer 构造简介上一节咱们提到了 NamedContextFactory,Spring Cloud LoadBalancer 这里也是应用了这个机制实现了不同微服务应用不同的 Spring Cloud LoadBalancer 配置。相干外围实现是 @LoadBalancerClient 和 @LoadBalancerClients 这两个注解,以及 NamedContextFactory.Specification 的实现 LoadBalancerClientSpecification,NamedContextFactory 的实现 LoadBalancerClientFactory。 ...

May 28, 2021 · 3 min · jiezi

关于spring-cloud:Spring-Cloud-升级之路-20200x-5-理解-NamedContextFactory

spring-cloud-commons 中参考了 spring-cloud-netflix 的设计,引入了 NamedContextFactory 机制,个别用于对于不同微服务的客户端模块应用不同的 子 ApplicationContext 进行配置。 spring-cloud-commons 是 Spring Cloud 对于微服务根底组件的形象。在一个微服务中,调用微服务 A 与调用微服务 B 的配置可能不同。比较简单的例子就是,A 微服务是一个简略的用户订单查问服务,接口返回速度很快,B 是一个报表微服务,接口返回速度比较慢。这样的话咱们就不能对于调用微服务 A 和微服务 B 应用雷同的超时工夫配置。还有就是,咱们可能对于服务 A 通过注册核心进行发现,对于服务 B 则是通过 DNS 解析进行服务发现,所以对于不同的微服务咱们可能应用不同的组件,在 Spring 中就是应用不同类型的 Bean。 在这种需要下,不同微服务的客户端有不同的以及雷同的配置,有不同的 Bean,也有雷同的 Bean。所以,咱们能够针对每一个微服务将他们的 Bean 所处于 ApplicationContext 独立开来,不同微服务客户端应用不同的 ApplicationContext。NamedContextFactory 就是用来实现这种机制的。 通过实例理解 NamedContextFactory 的应用编写源码: package com.github.hashjang.spring.cloud.iiford.service.common;import org.junit.Assert;import org.junit.Test;import org.springframework.cloud.context.named.NamedContextFactory;import org.springframework.context.annotation.AnnotationConfigApplicationContext;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.core.env.Environment;import java.util.List;import java.util.Objects;public class CommonNameContextTest { private static final String PROPERTY_NAME = "test.context.name"; @Test public void test() { //创立 parent context AnnotationConfigApplicationContext parent = new AnnotationConfigApplicationContext(); //增加 BaseConfig 相干配置 parent.register(BaseConfig.class); //初始化 parent parent.refresh(); //创立 testClient1,默认配置应用 ClientCommonConfig TestClient testClient1 = new TestClient(ClientCommonConfig.class); //创立 service1 与 service2 以及指定对应额定的配置类 TestSpec testSpec1 = new TestSpec("service1", new Class[]{Service1Config1.class, Service1Config2.class}); TestSpec testSpec2 = new TestSpec("service2", new Class[]{Service2Config.class}); //设置 parent ApplicationContext 为 parent testClient1.setApplicationContext(parent); //将 service1 与 service2 的配置退出 testClient1 testClient1.setConfigurations(List.of(testSpec1, testSpec2)); BaseBean baseBean = testClient1.getInstance("service1", BaseBean.class); System.out.println(baseBean); //验证失常获取到了 baseBean Assert.assertNotNull(baseBean); ClientCommonBean commonBean = testClient1.getInstance("service1", ClientCommonBean.class); System.out.println(commonBean); //验证失常获取到了 commonBean Assert.assertNotNull(commonBean); Service1Bean1 service1Bean1 = testClient1.getInstance("service1", Service1Bean1.class); System.out.println(service1Bean1); //验证失常获取到了 service1Bean1 Assert.assertNotNull(service1Bean1); Service1Bean2 service1Bean2 = testClient1.getInstance("service1", Service1Bean2.class); System.out.println(service1Bean2); //验证失常获取到了 service1Bean2 Assert.assertNotNull(service1Bean2); BaseBean baseBean2 = testClient1.getInstance("service2", BaseBean.class); System.out.println(baseBean2); //验证失常获取到了 baseBean2 并且 baseBean2 就是 baseBean Assert.assertEquals(baseBean, baseBean2); ClientCommonBean commonBean2 = testClient1.getInstance("service2", ClientCommonBean.class); System.out.println(commonBean2); //验证失常获取到了 commonBean2 并且 commonBean 和 commonBean2 不是同一个 Assert.assertNotNull(commonBean2); Assert.assertNotEquals(commonBean, commonBean2); Service2Bean service2Bean = testClient1.getInstance("service2", Service2Bean.class); System.out.println(service2Bean); //验证失常获取到了 service2Bean Assert.assertNotNull(service2Bean); } @Configuration(proxyBeanMethods = false) static class BaseConfig { @Bean BaseBean baseBean() { return new BaseBean(); } } static class BaseBean {} @Configuration(proxyBeanMethods = false) static class ClientCommonConfig { @Bean ClientCommonBean clientCommonBean(Environment environment, BaseBean baseBean) { //在创立 NamedContextFactory 外面的子 ApplicationContext 的时候,会指定 name,这个 name 对应的属性 key 即 PROPERTY_NAME return new ClientCommonBean(environment.getProperty(PROPERTY_NAME), baseBean); } } static class ClientCommonBean { private final String name; private final BaseBean baseBean; ClientCommonBean(String name, BaseBean baseBean) { this.name = name; this.baseBean = baseBean; } @Override public String toString() { return "ClientCommonBean{" + "name='" + name + '\'' + ", baseBean=" + baseBean + '}'; } } @Configuration(proxyBeanMethods = false) static class Service1Config1 { @Bean Service1Bean1 service1Bean1(ClientCommonBean clientCommonBean) { return new Service1Bean1(clientCommonBean); } } static class Service1Bean1 { private final ClientCommonBean clientCommonBean; Service1Bean1(ClientCommonBean clientCommonBean) { this.clientCommonBean = clientCommonBean; } @Override public String toString() { return "Service1Bean1{" + "clientCommonBean=" + clientCommonBean + '}'; } } @Configuration(proxyBeanMethods = false) static class Service1Config2 { @Bean Service1Bean2 service1Bean2() { return new Service1Bean2(); } } static class Service1Bean2 { } @Configuration(proxyBeanMethods = false) static class Service2Config { @Bean Service2Bean service2Bean(ClientCommonBean clientCommonBean) { return new Service2Bean(clientCommonBean); } } static class Service2Bean { private final ClientCommonBean clientCommonBean; Service2Bean(ClientCommonBean clientCommonBean) { this.clientCommonBean = clientCommonBean; } @Override public String toString() { return "Service2Bean{" + "clientCommonBean=" + clientCommonBean + '}'; } } static class TestSpec implements NamedContextFactory.Specification { private final String name; private final Class<?>[] configurations; public TestSpec(String name, Class<?>[] configurations) { this.name = name; this.configurations = configurations; } @Override public String getName() { return name; } @Override public Class<?>[] getConfiguration() { return configurations; } } static class TestClient extends NamedContextFactory<TestSpec> { public TestClient(Class<?> defaultConfigType) { super(defaultConfigType, "testClient", PROPERTY_NAME); } }}后果输入为: ...

May 26, 2021 · 4 min · jiezi

关于springcloud:SpringCloud入门2Ribbon

Ribbon是客户端的负载均衡器,消费者能够通过服务别名调用服务时,须要Ribbon做负载平衡来以某种机制拜访理论的服务调用地址。 简略类比,咱们去找Tony老师,个别理发店都会有多个Tony老师。然而也会有一个相似前台的工作人员为咱们安顿有空的Tony老师理发。工作人员就是相似Ribbon,是依照程序安顿呢,还是随机安顿呢。 Ribbon + Eureka创立我的项目同样创立一个Ribbon的空模块,而后在Ribbon空模块下创立一个ribbon-consume9101 子模块。在父类也就是空模块的pom文件中退出依赖 <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> </dependency></dependencies>当你引入了Eureka相干的依赖的时候其实就曾经把Ribbon的依赖引入进来了,所以如果应用的是Ribbon + Eureka,能够不必写下面的依赖也能运行。 创立实现后整体的我的项目构造如图所示 配置文件application.yml server: port: 9101spring: application: name: ribbon-consumeeureka: client: fetch-registry: true register-with-eureka: true service-url: defaultZone: http://localhost:8001/eureka/ instance: instance-id: ribbon-consume9101启动和业务类留神咱们的服务的提供者是eureka-provide 服务,这个服务名字可能单取provide 更精确点,当前我的项目重构的时候可能会批改。 波及到服务与服务之间的调用,个别会抉择应用RestTemplate ,同时须要把它注入Spring容器中,所以抉择应用配置类 @Configurationpublic class ApplicationContextConfig { @Bean @LoadBalanced //负载平衡须要的注解 public RestTemplate getRestTemplate() { return new RestTemplate(); }}接下来就是主启动类 @SpringBootApplication@EnableEurekaClient@RestControllerpublic class RibbonConsume9101 { final String PROVIDE_URL = "http://eureka-provide"; RestTemplate restTemplate; public RibbonConsume9101(RestTemplate restTemplate) { this.restTemplate = restTemplate; } @GetMapping("/ribbon/consume") public String getInfo() { return "i am consumer, but actually invoke other service: [" + restTemplate.getForObject(PROVIDE_URL + "/eureka/provide", String.class) + "]"; } public static void main(String[] args) { SpringApplication.run(RibbonConsume9101.class, args); }}测试开启Eureak注册核心EurekaServer8001开启3个不同端口的服务提供者EurekaProvide7001 ,EurekaProvide7002 , EurekaProvide7003开启刚刚建设的Ribbon消费者RibbonConsume9101首先看下Eureka注册核心,能够看到3个服务提供者,1个消费者都曾经注册到Eureka。 ...

May 25, 2021 · 2 min · jiezi

关于springcloud:一个实例轻松演示Spring-Cloud集成Nacos实例

前言学习一个技术框架,最疾速的伎俩就是将其集成到我的项目中,体验一下它的性能。在这个过程中,你还踩到很多坑。而排坑的过程,又是一次能力的晋升。 后面咱们写了一些列Nacos的文章,通过《学习Nacos?咱先把服务搞起来,实战教程》的介绍,咱们曾经能够把Nacos Server给启动起来了。 这篇文章,咱们就来学习一下如何将Nacos集成到Spring Cloud我的项目中,同时实例演示一下,基于Nacos的微服务之间的两种调用模式。 集成与版本为了演示这个案例,大家首先要将Nacos Server跑起来。同时会构建两个微服务:服务提供方(Provider)和服务生产方(Consumer)。而后,通过两个服务之间的调用及配合查看Nacos Server中的注册信息来进行验证。 咱们晓得,Nacos隶属于Spring Cloud Alibaba系列中的组件。所以,在进行集成之前,有一件事肯定要留神,那就是要确保Spring Cloud、Spring Boot、Spring Cloud Alibaba版本的统一。不然产生一些莫名其妙的异样。 对于版本信息能够在https://spring.io/projects/sp... 这里采纳Spring Boot的版本为2.4.2,Spring Cloud采纳2020.0.0、Spring Cloud Alibaba采纳2021.1。如你采纳其余版本,肯定确保对照关系。 Nacos服务提供者依赖配置创立我的项目Spring Boot的我的项目spring-cloud-alibaba-nacos-provider1,在pom文件中增加定义依赖的版本限度: <properties> <java.version>1.8</java.version> <spring-boot.version>2.4.2</spring-boot.version> <spring-cloud.version>2020.0.0</spring-cloud.version> <cloud-alibaba.version>2021.1</cloud-alibaba.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> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>${cloud-alibaba.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies></dependencyManagement>而后增加依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId></dependency><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency>其中actuator为健康检查依赖包,nacos-discovery为服务发现的依赖包。 配置文件提供者增加配置(application.yml) server: port: 8081spring: application: name: user-service-provider cloud: nacos: discovery: server-addr: 127.0.0.1:8848其中Nacos Server的地址和端口号默认是127.0.0.1:8848。name用来指定此服务的名称,消费者可通过注册的这个名称来进行申请。 业务代码在编写业务代码之前,咱们先来看一下提供者的启动类: // 版本不同,低版本须要明确应用@EnableDiscoveryClient注解//@EnableDiscoveryClient@SpringBootApplicationpublic class NacosProviderApplication { public static void main(String[] args) { SpringApplication.run(NacosProviderApplication.class, args); }}留神下面的正文局部,此版本曾经不须要@EnableDiscoveryClient注解了,而较低的版本须要增加对应的注解。 ...

May 25, 2021 · 2 min · jiezi

关于springcloud:打包微服务前后端分离项目并部署到服务器-分布式-Spring-Cloud-页面渲染-Nuxtjs

前言Spring Cloud我的项目属于微服务项目,也就是含有多个Sping Boot模块汇合而成的我的项目 Nuxt.js我的项目属于前端基于Vue的服务端渲染我的项目 最近在服务器部署上线了一个基于Spring Cloud + 服务端渲染技术Nuxt.js的我的项目,在这里记录一下 一、部署后端1、打包步骤: 在pom.xml中退出打包依赖在IDEA中点击clean、抉择install打包成jar包在target文件夹中能够看到打包的jar包留神:如果target文件夹中呈现多个jar包,.jar.original 是一般jar包,不蕴含依赖,.jar 是可执行jar包,蕴含了pom.xml中的所有依赖,能够间接用java -jar 命令执行。 打包Spring Cloud我的项目中的每个模块退出打包依赖 比方在gateway模块 在pom.xml退出以下代码 <build> <finalName>service-gateway</finalName> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> <resources> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> </resource> </resources></build>而后再IDEA中maven插件中点击 相互依赖的模块怎么打包?比方A模块依赖B模块,就须要在A模块援用B模块的依赖中退出<scope>compile</scope>,否则打包的时候会显示报错 A模块中的pom.xml文件 <dependency> <groupId>com.zfz</groupId> <artifactId>common-util</artifactId> <version>0.0.1-SNAPSHOT</version> <scope>compile</scope></dependency>再点击IDEA中的clean和install打包jar包 2、上传jar包到服务器保障须要的jar包和Dockerfile、docker-compose.yml文件在同一目录 3、构建镜像创立Dockerfile文件,举例gateway模块 FROM java:8MAINTAINER ADD service-gateway.jar app.jarEXPOSE 80ENTRYPOINT ["java","-jar","app.jar"] 在XShell命令行工具中输出以下命令,构建镜像 docker build -t service-gateway .以此类推,把所有想要构建的镜像都用以上命令构建进去 最初输出docker images查看构建镜像 4、运行容器创立docker-compose.yml文件 version: '3.1'services: service-gateway: image: service-gateway ports: - "80:80" restart: "always" container_name: service-gateway volumes: - /root/service-gateway.jar:/root/cloud/service-gateway.jar entrypoint: java -jar /root/cloud/service-gateway.jar 服务名: image: 已存在的镜像名称 ports: - 映射端口 restart: "always" container_name: 容器名称 volumes: - 挂载门路 entrypoint: 构建容器后,运行命令 ......在XShell命令行工具中输出以下命令,一键部署jar包 ...

May 24, 2021 · 1 min · jiezi

关于spring-cloud:学习Nacos咱先把服务搞起来实战教程

前言后面曾经写不少Nacos相干的文章了,比方《Spring Cloud集成Nacos服务发现源码解析?翻了三套源码,保质保鲜!》,而且目前也打算写一个Spring Cloud的技术解析专栏,一个技术框架一个技术框架的为大家拆解剖析原理和实现。 既然拿Nacos作为一个开始,那么咱们这篇文章就来补充一下Nacos Server的部署以及Nacos Client的调用,直观的理解一下Nacos都蕴含了什么性能。这是应用Nacos的根底,也是后续进行深度分析的根据。强烈建议一起学习一下。 Nacos Server的部署对于Nacos Server的部署,官网手册中曾经进行了很具体的阐明,对应链接地址(https://nacos.io/zh-cn/docs/d... )。其余形式的部署咱们暂且不说,咱们重点阐明通过源码的模式进行构建和部署,这也是学习的最好形式。 Nacos部署的根本环境要求:JDK 1.8+,Maven 3.2.x+,筹备好即可。 从Github上下载源码: // 下载源码git clone https://github.com/alibaba/nacos.git// 进入源码目录cd nacos/// 执行编译打包操作mvn -Prelease-nacos -Dmaven.test.skip=true clean install -U// 查看生成的jar包ls -al distribution/target/// 进入到打包好的文件目录,后续可执行启动cd distribution/target/nacos-server-$version/nacos/bin通过上述命令进入到bin目录下,通常有不同环境的启动脚本: shutdown.cmd shutdown.sh startup.cmd startup.sh执行对应环境的脚本即可进行启动,参数standalone代表着单机模式运行: // Linux/Unix/Macsh startup.sh -m standalone// ubuntubash startup.sh -m standalone// Windowsstartup.cmd -m standalone上述操作实用于打包和部署,也实用于本地启动服务,但如果是学源码,则能够间接执行console(nacos-console)中的main办法(Nacos类)即可。 执行main办法启动,默认也是集群模式,可通过JVM参数来指定单机启动: -Dnacos.standalone=true如果为了不便,也能够间接在启动类的源码中间接增加该参数: @SpringBootApplication(scanBasePackages = "com.alibaba.nacos")@ServletComponentScan@EnableSchedulingpublic class Nacos { public static void main(String[] args) { // 通过环境变量的模式设置单机启动 System.setProperty(Constants.STANDALONE_MODE_PROPERTY_NAME, "true"); SpringApplication.run(Nacos.class, args); }}通过上述步骤,咱们曾经能够启动一个Nacos Server了,前面就来看如何应用。 ...

May 21, 2021 · 2 min · jiezi

关于springcloud:Spring-Cloud集成Nacos服务发现源码解析翻了三套源码保质保鲜

后面文章咱们介绍了Nacos的性能及设计架构,这篇文章就以Nacos提供的服务注册性能为主线,来解说Nacos的客户端是如何在Spring Cloud进行集成和实现的。 本会配合源码剖析、流程图整顿、外围API解析等维度来让大家深入浅出、零碎的来学习。 Spring Boot的主动注册故事要从头Spring Boot的主动注入开始。很多敌人大略都理解过Spring Boot的主动配置性能,而Spring Cloud又是基于Spring Boot框架的。 因而,在学习Nacos注册业务之前,咱们先来回顾一下Spring Boot的主动配置原理,这也是学习的入口。 Spring Boot通过@EnableAutoConfiguration注解,将所有符合条件的@Configuration配置都加载到以后SpringBoot创立并应用的IoC容器。 上述过程是通过@Import(AutoConfigurationImportSelector.class)导入的配置性能,AutoConfigurationImportSelector中的办法getCandidateConfigurations,失去待配置的class的类名汇合,即所有须要进行主动配置的(xxxAutoConfiguration)类,这些类配置于META-INF/spring.factories文件中。 最初,依据这些全限定名类上的注解,如:OnClassCondition、OnBeanCondition、OnWebApplicationCondition条件化的决定要不要主动配置。 理解了Spring Boot的根本配置之后,咱们来看看Nacos对应的主动配置在哪里。 Spring Cloud中的Nacos主动配置查看Spring Cloud的我的项目依赖,自己引入依赖对应的jar包为spring-cloud-starter-alibaba-nacos-discovery-2021.1.jar; 对应的pom依赖为: <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency>查看jar包中META-INF/spring.factories文件的内容: org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.alibaba.cloud.nacos.discovery.NacosDiscoveryAutoConfiguration,\ com.alibaba.cloud.nacos.endpoint.NacosDiscoveryEndpointAutoConfiguration,\ com.alibaba.cloud.nacos.registry.NacosServiceRegistryAutoConfiguration,\ com.alibaba.cloud.nacos.discovery.NacosDiscoveryClientConfiguration,\ com.alibaba.cloud.nacos.discovery.reactive.NacosReactiveDiscoveryClientConfiguration,\ com.alibaba.cloud.nacos.discovery.configclient.NacosConfigServerAutoConfiguration,\ com.alibaba.cloud.nacos.NacosServiceAutoConfigurationorg.springframework.cloud.bootstrap.BootstrapConfiguration=\ com.alibaba.cloud.nacos.discovery.configclient.NacosDiscoveryClientConfigServiceBootstrapConfiguration能够看到EnableAutoConfiguration类对应了一系列的Nacos主动配置类。 其中NacosServiceRegistryAutoConfiguration是用来封装实例化Nacos注册流程所需组件的,装载了对三个对象NacosServiceRegistry、NacosRegistration、NacosAutoServiceRegistration,这三个对象整体都是为了Nacos服务注册应用的。 @Configuration(proxyBeanMethods = false)@EnableConfigurationProperties@ConditionalOnNacosDiscoveryEnabled@ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled", matchIfMissing = true)@AutoConfigureAfter({ AutoServiceRegistrationConfiguration.class, AutoServiceRegistrationAutoConfiguration.class, NacosDiscoveryAutoConfiguration.class })public class NacosServiceRegistryAutoConfiguration { @Bean public NacosServiceRegistry nacosServiceRegistry( NacosDiscoveryProperties nacosDiscoveryProperties) { return new NacosServiceRegistry(nacosDiscoveryProperties); } @Bean @ConditionalOnBean(AutoServiceRegistrationProperties.class) public NacosRegistration nacosRegistration( ObjectProvider<List<NacosRegistrationCustomizer>> registrationCustomizers, NacosDiscoveryProperties nacosDiscoveryProperties, ApplicationContext context) { return new NacosRegistration(registrationCustomizers.getIfAvailable(), nacosDiscoveryProperties, context); } @Bean @ConditionalOnBean(AutoServiceRegistrationProperties.class) public NacosAutoServiceRegistration nacosAutoServiceRegistration( NacosServiceRegistry registry, AutoServiceRegistrationProperties autoServiceRegistrationProperties, NacosRegistration registration) { return new NacosAutoServiceRegistration(registry, autoServiceRegistrationProperties, registration); }}其中NacosServiceRegistry封装的就是注册流程,它继承自ServiceRegistry: ...

May 20, 2021 · 1 min · jiezi

关于spring-cloud:Eurynome-Cloud-微服务能力管理和开发平台

Eurynome Cloud 微服务能力治理和开发平台Eurynome Cloud是一款微服务能力治理和开发平台。基于SpringBoot2.4.5、Spring Cloud 2020.0.2、Spring Cloud Alibaba 2021.1、Nacos 2.0.1等最新版本开发,遵循SpringBoot编程思维,高度模块化和可配置化。具备服务发现、配置、熔断、限流、降级、监控、多级缓存、分布式事务、工作流等性能,代码简洁,架构清晰,非常适合学习和企业作为根底框架应用。 1、性能介绍 特点: 优化的代码分包和包依赖,代码包职责明确,躲避无意义的依赖以及反复依赖,对根底依赖组件进行高度封装,升高IDE索引工夫,晋升开发效率遵循微服开发模式,强化整体的可配置性,依赖性能均能够通过@EnableXXX开启,反对策略化的注入扭转局部外围代码的实现逻辑。提供的starter,开箱即用,可零配置创立服务,疾速进行开发基于JetCache自研缓存拓展,反对分页和条件查问缓存动静更新拓展OAuth2默认登录,反对多种验证码和登录数据加密传输,可通过配置进行自定义设置。多数据库反对,默认采纳Postgresql数据库,同时反对Spring Data Jpa 和Mybatis多种音讯队列反对,适配RabbitMQ和Kafka,默认应用Kafka,反对音讯总线(Spring Cloud Bus)Rest接口自动化扫描生成权限数据,反对扫描包和扫描注解动静配置采纳Camunda实现工作流服务,反对在线编辑同时反对分布式和单体式两种架构,基于单体式架构可疾速搭建基于OAuth2的前后端拆散利用共享式、统一化多环境配置模式,Yml、Docker均采纳此形式配置,防止同类配置多出批改的问题2、技术栈和版本阐明(1)Spring全家桶及核心技术版本组件版本Spring Boot2.4.5Spring Cloud2020.0.2Spring Cloud Alibaba2021.1Spring Boot Admin2.4.1Nacos2.0.1 Sentinel1.8.0 Seata1.3.0 Spring 全家桶版本对应关系,详见:版本阐明(2)所波及的相干的技术:JSON序列化:Jackson & FastJson音讯队列:Kafka 适配RabbitMQ,反对音讯总线(Spring Cloud Bus)数据缓存:JetCache + Redis (两级缓存)数据库: Postgresql,MySQL,Oracle ...前端实现:Vue + Vuetify(单体版Vue + Vuetify + Typescript + 模块化)长久层框架: Spring Data Jpa & MybatisAPI网关:Gateway服务注册&发现和配置核心: Nacos服务生产:OpenFeign & RestTemplate & OkHttp3负载平衡:Ribbon服务熔断&降级&限流:Sentinel我的项目构建:Maven分布式事务:Seata服务监控:Spring Boot Admin链路跟踪:Skywalking文件服务:阿里云OSS/Minio数据调试:p6spy日志核心:ELK日志收集:Logstash Logback Encoder3、 版本号阐明本零碎版本号,分为四段。 第一段和第二段,与Spring Boot 版本对应,依据采纳的Spring Boot版本变更。例如,以后采纳Spring Boot 2.4.5版本,那么就以2.4.X.X结尾第三段,示意零碎性能的变动第四段,示意零碎性能保护及优化状况4、工程构造eurynome-cloud├── configurations -- 配置文件脚本和对立Docker build上下文目录├── dependencies -- 工程Maven顶级依赖,对立管制版本和依赖├── documents -- 工程相干文档├── packages -- 根底通用依赖包├ ├── eurynome-cloud-common -- 公共工具类├ ├── eurynome-cloud-data -- 数据长久化、数据缓存以及Redis等数据处理相干代码组件├ ├── eurynome-cloud-rest -- Rest相干代码组件├ ├── eurynome-cloud-crud -- CRUD相干代码组件├ ├── eurynome-cloud-sercurity -- Security通用代码├ ├── eurynome-cloud-oauth -- OAuth2通用代码├ ├── eurynome-cloud-message -- 音讯队列、BUG相干代码组件├ ├── eurynome-cloud-kernel -- 微服务接入平台必备组件├ ├── eurynome-cloud-oauth-starter -- 自定义OAuth2 Starter├ └── eurynome-cloud-starter -- 微服务外围Starter├── platform -- 平台外围服务├ ├── eurynome-cloud-gateway -- 服务网关├ ├── eurynome-cloud-management -- Spring Boot Admin 监控服务├ └── eurynome-cloud-uaa -- 对立认证模块├── services -- 平台业务服务├ ├── eurynome-cloud-upms-api -- 通用用户权限api ├ ├── eurynome-cloud-upms-logic -- 通用用户权限service├ ├── eurynome-cloud-upms-rest -- 通用用户权限rest 接口├ ├── eurynome-cloud-upms-ability -- 通用用户权限服务└── └── eurynome-cloud-bpmn-ability -- 工作流服务 5、我的项目地址后端Gitee地址:https://gitee.com/herodotus/eurynome-cloud单体版示例工程:https://gitee.com/herodotus/eurynome-cloud-athena前端Gitee地址:https://gitee.com/herodotus/eurynome-cloud-ui6、开源协定Apache Licence 2.0 (英文原文) Apache Licence是驰名的非盈利开源组织Apache采纳的协定。该协定和BSD相似,同样激励代码共享和尊重原作者的著作权,同样容许代码批改,再公布(作为开源或商业软件)。 须要满足的条件如下: ...

May 18, 2021 · 1 min · jiezi

关于springcloud:SpringCloud入门一Eureka

在后期筹备的文章中也说过了Spring Cloud的5大组件,明天就来讲讲服务发现(注册)。无论是Spring Cloud H版还是最新的版本,Eureka都是作为服务发现和注册的罕用组件。 我的项目搭建构建一个eureka的父模块,具体怎么实现能够参考前篇文章。 在空我的项目外面构建2个模块 eureka的服务端,eureka的客户端,其中客户端在本例仅包含服务的生产者。Eureka父模块的pom文件如下,为了不便间接引入了server和client <?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"> <parent> <artifactId>spring-cloud-learning</artifactId> <groupId>com.cutey.none</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>eureka</artifactId> <packaging>pom</packaging> <modules> <module>eureka-server8001</module> <module>eureka-client-provide7001</module> <module>eureka-client-consume9001</module> </modules> <properties> <maven.compiler.source>9</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> </properties> <dependencies> <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-eureka-client</artifactId> </dependency> </dependencies></project>能够看到pom文件中指明了父模块,同时也继承了父模块的依赖。全副实现后,我的我的项目构造如下图所示: 我的项目的规约,不肯定是和真正开发一样,然而为了不便记忆: 服务注册核心的端口为8xxx生产端的端口为7xxx生产端的端口为9xxx Eureka Server在上一步的pom文件中就曾经通过maven导入了Eureka Server的依赖。如果没有在父模块中导入,则需退出上面的代码: <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></dependency>接下来要做的就是减少配置文件和启动类以及业务代码的编写。 配置文件 application.yml server: port: 8001eureka: instance: hostname: localhost client: register-with-eureka: false fetch-registry: false service-url: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/留神我这里的端口是8001,然而eureka默认的端口是8761,这个端口能够自行批改,所以问题不大。 还有一个须要留神的点是,defaultZone 是肯定须要的,官网文档外面是说service-url 是以键值对的模式存储,所以必须要有key和value。 启动类 @SpringBootApplication@EnableEurekaServerpublic class EurekaServer8001 { public static void main(String[] args) { SpringApplication.run(EurekaServer8001.class, args); }}次要是加了一个@EnableEurekaServer 的注解,因为是服务端的起因,在这种demo中就没有增加其它多余的业务类。 ...

May 17, 2021 · 1 min · jiezi

关于springcloud:IDEA-创建基于SpringCloud多模块项目

前言最近开始学习SpringCloud 2020.0.2新的版本,筹备应用全新的架构,如图所示所以记录下应用idea创立多模块我的项目,一步一步记录搭建的过程 创立我的项目(New Project) 增加模块(New Module) 援用SpringCloud前置操作1、删除ztosin-parent我的项目下的src目录2、批改ztosin-parent我的项目的的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> <artifactId>ztosin-nacossvr</artifactId> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.4.5</version> </parent> <properties> <spring.cloud-version>2020.0.2</spring.cloud-version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </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> <build> <plugins> <plugin> <groupId>com.spotify</groupId> <artifactId>dockerfile-maven-plugin</artifactId> <version>1.4.10</version> <configuration> <dockerfile>src/main/docker/Dockerfile</dockerfile> <!-- <repository>spotify/foobar</repository>--> <!--<tag>${project.version}</tag>--> <buildArgs> <!--提供参数向Dockerfile传递--> <JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE> </buildArgs> </configuration> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build></project>3、增加NacosServerApplication.java package com.ztosin.nacossvr;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublic class NacosServerApplication { public static void main(String[] args) { SpringApplication.run(NacosServerApplication.class, args); }}最终目录构造如下所示 : ...

May 12, 2021 · 1 min · jiezi

关于spring-cloud:Spring-Cloud-Bus-消息总线介绍

简介: 本文配套可交互教程已登录阿里云知口头手实验室,PC 端登录 start.aliyun.com 在浏览器中立刻体验。 作者 | 洛夜起源 | 阿里巴巴云原生公众号 本文配套可交互教程已登录阿里云知口头手实验室,PC 端登录 start.aliyun.com 在浏览器中立刻体验。 Spring Cloud Bus 对本人的定位是 Spring Cloud 体系内的音讯总线,应用 message broker 来连贯分布式系统的所有节点。Bus 官网的 Reference 文档 比较简单,简略到连一张图都没有。 这是最新版的 Spring Cloud Bus 代码构造(代码量比拟少): Bus 实例演示在剖析 Bus 的实现之前,咱们先来看两个应用 Spring Cloud Bus 的简略例子。 1. 所有节点的配置新增Bus 的例子比较简单,因为 Bus 的 AutoConfiguration 层都有了默认的配置,只须要引入消息中间件对应的 Spring Cloud Stream 以及 Spring Cloud Bus 依赖即可,之后所有启动的利用都会应用同一个 Topic 进行音讯的接管和发送。 Bus 对应的 Demo 曾经放到了 github 上, 该 Demo 会模仿启动 5 个节点,只须要对其中任意的一个实例新增配置项,所有节点都会新增该配置项。 ...

May 12, 2021 · 4 min · jiezi

关于spring-cloud:Spring-Cloud-升级之路-20200x-4-使用-Eureka-作为注册中心

Eureka 目前的状态:Eureka 目前 1.x 版本还在更新,然而应该不会更新新的性能了,只是对现有性能进行保护,降级并兼容所需的依赖。 Eureka 2.x 曾经胎死腹中了。然而,这也不代表 Eureka 就是不能用了。如果你须要一个简便易于部署的注册核心,Eureka 还是一个很好的抉择。云服务环境中,基本上所有实例地址和微服务名称都在一直变动,也并不太须要 Eureka 所短少的长久化个性。当你的集群属于中小规模的时候(节点小于 1000 个), Eureka 仍然是一个不错的抉择。当你的集群很大的时候,Eureka 的同步机制可能就限度了他的体现。 Eureka 的设计Eureka 的设计比拟玲珑,没有简单的同步机制,也没有简单的长久化机制,集群关系只是简略的将收到的客户端申请转发到集群内的其余 Eureka 实例。Eureka 自身也只有注册核心的性能,不像其余品种的注册核心那样,将注册核心和配置核心合在一起,例如 Consul 和 nacos。 Eureka 的交互流程如下: 首先,Service A 通过 Eureka Client 发送注册申请(Register)到同一可用区的 Eureka Server 1。之后通过发送心跳申请(Renew)到这个 Eureka Server 1. Eureka Server 1 收到这些申请的时候,会解决这些申请并将这些申请转发到其余的集群内的 Eureka Server 2 和 Eureka Server 3. Eureka Server 2 和 Eureka Server 3 不会再转发收到的 Eureka Server 1 转发过去的申请。而后,Service B 还有 Service C 通过 Eureka 获取到了 Service A 的地位,最初调用了 Service A。 ...

May 10, 2021 · 5 min · jiezi

关于springcloud:分布式服务熔断降级限流利器至Hystrix

原文地址1 原文地址2 全文概览 [TOC] 为什么须要hystrixhystrix官网地址github Hystrix同样是netfix公司在分布式系统中的奉献。同样的也进入的不维护阶段。不保护不代表被淘汰。只能阐明新陈代谢技术在一直迭代。曾今的辉煌已经的设计还是值得咱们去学习的。在分布式环境中,服务调度是特色也是头疼的一块。在服务治理章节咱们介绍了服务治理的性能。前一课咱们也介绍了ribbon、feign进行服务调用。当初天然的到了服务监控治理了。hystrix就是对服务进行隔离爱护。以实现服务不会呈现连带故障。导致整个零碎不可用 如上图所示,当多个客户端进行服务调用Aservice时,而在分布式系统中Aservice存在三台服务,其中Aservice某些逻辑须要Bservice解决。Bservice在分布式系统中部署了两台服务。这个时候因为网络问题导致Aservice中有一台和Bservice的通信异样。如果Bservice是做日志解决的。在整个零碎看来日志丢了和零碎宕机比起来应该无所谓了。然而这个时候因为网络通信问题导致Aservice整个服务不可用了。有点得不尝试。 在看上图 。 A-->B-->C-->D 。此时D服务宕机了。C因为D宕机呈现解决异样。然而C的线程却还在为B响应。这样随着并发申请进来时,C服务线程池呈现爆满导致CPU上涨。在这个时候C服务的其余业务也会受到CPU上涨的影响导致响应变慢。特色性能Hystrix是一个低提早和容错的第三方组件库。旨在隔离近程零碎、服务和第三方库的拜访点。官网上曾经进行保护并举荐应用resilience4j。然而国内的话咱们有springcloud alibaba。 Hystrix 通过隔离服务之间的拜访来实现分布式系统中提早及容错机制来解决服务雪崩场景并且基于hystrix能够提供备选计划(fallback)。 对网络提早及故障进行容错阻断分布式系统雪崩疾速失败并平缓复原服务降级实时监控、警报$$99.99^{30} = 99.7\% \quad uptime\\0.3\% \quad of \quad 1 \quad billion \quad requests \quad = \quad 3,000,000 \quad failures\\2+ \quad hours \quad downtime/month \quad even \quad if \quad all \quad dependencies \quad have \quad excellent \quad uptime.$$ 上面试官网给出的一个统计。在30台服务中每台出现异常的概览是0.01%。一亿个申请就会有300000失败。这样换算下每个月至多有2小时停机。这对于互联网零碎来说是致命的。 上图是官网给出的两种状况。和咱们上章节的相似。都是介绍服务雪崩的场景。我的项目筹备在openfeign专题中咱们就探讨了基于feign实现的服务熔断过后说了外部就是基于hystrix。过后咱们也看了pom外部的构造在eureka中内置ribbon的同时也内置了hystrix模块。 尽管包外面蕴含了hystrix 。咱们还是引入对应的start开启相干配置吧。这里其实就是在openfeign专题中的列子。在那个专题咱们提供了PaymentServiceFallbackImpl、PaymentServiceFallbackFactoryImpl两个类作为备选计划。不过过后咱们只需指出openfeign反对设置两种形式的备选计划。明天咱们 <!--hystrix--><dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId></dependency>演示下传统企业没有备选计划的状况会产生什么劫难。 接口测试首先咱们对payment#createByOrder接口进行测试。查看下响应状况 在测试payment#getTimeout/id办法。 当初咱们用jemeter来压测payment#getTimeOut/id这个接口。一位须要4S期待会照成资源耗费殆尽问题。这个时候咱们的payment#createByOrder也会被阻塞。 spring中默认的tomcat的最大线程数是200.为了爱护咱们辛苦的笔记本。这里咱们将线程数设置小点。这样咱们更容易复现线程被打满的状况。线程满了就会影响到payment#createByOrder接口。 下面咱们压测的是payment的原生接口。如果压测的是order模块。如果没有在openfeign中配置fallback。那么order服务就会因为payment#getTimeOut/id接口并发导致线程满了从而导致order模块响应迟缓。这就是雪崩效应。上面咱们从两个方面来解决雪崩的产生。业务隔离下面的场景产生是因为payment#createByOrder 和payment#getTimeOut/id同属于payment服务。一个payment服务实际上就是一个Tomcat服务。同一个tomcat服务是有一个线程池的。 每次申请落到该tomcat 服务里就会去线程池中申请线程。获取到线程了能力由线程来解决申请的业务。就是因为tomcat内共享线程池。所以当payment#getTimeOut/id并发上来后就会抢空线程池。导致别的借口甚至是息息相关的接口都没有资源能够申请。只能水灵灵的期待资源的开释。这就好比下班高峰期乘坐电梯因为某一个公司集中下班导致一段时间电梯全副被应用了。这时候国家领导过去也没方法上电梯。咱们也晓得这种状况很好解决。每个园区都会有专用电梯供非凡应用。咱们解决上述问题也是同样的思路。进行隔离。不同的接口有不同的线程池。这样就不会造成雪崩。线程隔离 ...

April 27, 2021 · 3 min · jiezi

关于springcloud:nacos-config中遇到的问题解决

应用中遇到的问题,记录一下 启动报错 NacosConfigProperties : create config service error!properties=NacosConfigProperties{serverAddr='null', encode='null', group='DEFAULT_GROUP', prefix='null', fileExtension='properties', timeout=3000, endpoint='null', namespace='null', accessKey='null', secretKey='null', contextPath='null', clusterName='null', name='null', sharedDataids='null', refreshableDataids='null', extConfig=null},e=,但在我的项目中应用application.properties做了如下配置 spring.cloud.nacos.config.server-addr=localhost:8848为何还会报错?发现起因:pom.xml中应用了如下依赖 <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency>所以应用Nacos Config做对立配置管理时,启动springboot我的项目初始化都是应用bootstrap.properties配置文件去初始化上下文。将application.properties重命名为bootstrap.properties问题解决

April 2, 2021 · 1 min · jiezi

关于springcloud:SpringCloudsleuthzipkinrabbitmq

sleuth链路跟踪生成链路跟踪日志的工具 sleuth的实现第一步:在sp02、03、04、11中别离增加sleuth依赖 <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-sleuth</artifactId></dependency>第二步:通过控制台查看链路管制日志启动服务器,通过 zuul 网关,拜访 order-service,查看链路跟踪日志。http://localhost:3001/order-service/112233 sleuth+rabbitmq+zipkin第一步:sp02、03、04、11增加zipkin客户端依赖、amqp依赖 <!-- 增加zipkin、rabbitmq依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zipkin</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency>第二步:配置yml文件,增加rabbitmq的连贯信息到本地config文件夹并推送到git增加rabbitmq和zipkin配置。 spring: application: name: item-service #设置禁止配置核心的配置将客户端配置笼罩掉 cloud: config: override-none: true rabbitmq: host: 192.168.64.140 username: admin password: admin zipkin: sender: type: rabbit第三步:在cmd窗口启动zipkin 执行命令:java -jar zipkin-server-2.12.9-exec.jar --zipkin.collector.rabbitmq.uri=amqp://admin:admin@192.168.64.140:5672第四步:拜访测试关上zipkin服务器页面:http://localhost:9411/zipkin发送order-server服务器申请:刷新拜访屡次,链路跟踪数据中,默认只有 10% 会被收集到zipkinhttp://localhost:3001/order-service/112233

March 3, 2021 · 1 min · jiezi

关于springcloud:spring-cloud

spring cloud是一系列框架的汇合。它利用spring boot的开发便利性奇妙地简化了分布式系统基础设施的开发,如服务发现注册、配置核心、音讯总线、负载平衡、断路器、数据监控等,都能够用spring boot 的开发格调做到一键启动和部署。spring cloud并没有反复制作轮子,它只是将目前各家公司开发的比拟成熟、经得起理论考验的服务框架组合起来,通过spring boot格调进行再封装屏蔽掉了简单的配置和实现原理,最终给开发者留出了一套简略易懂、易部署和易保护的分布式系统开发工具包。spring cloud 对于中小型互联网公司来说是一种福音,因为这类公司往往没有实力或者没有足够的资金投入去开发本人的分布式系统基础设施,应用spring cloud一站式解决方案能在从容应对业务倒退的同时大大减少开发成本。同时,随着近几年微服务架构和docker容器概念的火爆,也会让spring cloud 在将来越来越“云”化的软件开发格调中立有一席之地,尤其是在目前形形色色的分布式解决方案中提供了标准化的、一站式的技术计划,意义可能会堪比当年servlet标准的诞生,无效推动服务端软件系统技术水平的提高。 spring cloudEureka----注册核心Cinfig----配置核心&默认Git存储Bus----音讯总线&动静配置刷新Ribbon----负载平衡&重试Hystrix----降级&熔断Feign----申明式客户端&集成Ribbon&集成HystrixZuul----API网关&过滤器&集成Ribbon&集成HystrixHystrix dashboard----Hystrix仪表盘Turbine----聚合Hystrix监控数据Sleuth+Zipkin----链路跟踪 Spring Cloud 比照 DubboDubbo----Dubbo只是一个近程调用(RPC)框架,默认基于长连贯,反对多种序列化格。Spring CloudSpring Cloud----框架集,提供了一整套微服务解决方案(全家桶),基于http调用,Rest API 一、service-服务商品服务 item service,端口 8001用户服务 user service,端口 8101订单服务 order service,端口 8201 二、commons通用我的项目新建maven我的项目 减少依赖--pom.xml <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> <groupId>cn.tedu</groupId> <artifactId>sp01-commons</artifactId> <version>0.0.1-SNAPSHOT</version> <name>sp01-commons</name> <dependencies> <dependency> <groupId>com.fasterxml.jackson.module</groupId> <artifactId>jackson-module-parameter-names</artifactId> <version>2.9.8</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-jdk8</artifactId> <version>2.9.8</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-jsr310</artifactId> <version>2.9.8</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-guava</artifactId> <version>2.9.8</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.6</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.26</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.9</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.0</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build></project>pojoItem ...

February 24, 2021 · 10 min · jiezi

关于springcloud:nacos注册中心

NACOS nacos是阿里开源的微服务注册核心+配置核心.本文次要讲nacos作为配置核心的性能.相比传统的Spring Cloud Config须要bus音讯总线+音讯队列来实现配置动静刷新,nacos本身即可刷新配置,极大简化的开发成本. nacos的注册核心与配置核心离开应用不同的jar包,本文只应用nacos-config. <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency>nacos属性namespace 命名空间,通常用于辨别dev/master等运行环境.默认即publicgroup 第二层级,通常用来划分我的项目.默认即DEFAULT_GROUPPData IddataId应用${spring.application.name}-${spring.profile.active}.${spring.cloud.nacos.config.file-extension}**.其中**-active**可省略,即**${spring.application.name}.${spring.cloud.nacos.config.file-extension}. 一些多环境通用配置项能够应用这种形式来配置. file-extension 反对yml和propertiesymlspring: application: name: nacos-config profiles: active: online cloud: nacos: config: server-addr: localhost:1111 file-extension: ymlserver: port: 8084应用@RefreshScope注解来实现配置动静刷新 @RefreshScopepublic class NacosController { @Value("${trevis.hobby}") private String hobby;配置共享应用${spring.application.name}.${spring.cloud.nacos.config.file-extension}形式. 2.应用shared-configs spring: application: name: nacos-config profiles: active: dev cloud: nacos: config: server-addr: localhost:1111 file-extension: yml shared-configs: nacos-config-shared.yml

February 20, 2021 · 1 min · jiezi

关于spring-cloud:Spring-Cloud-2020-bootstrap-配置文件失效

Spring Cloud 2020版本 bootstrap 配置文件(properties 或者 yml)有效 如何解决? 背景介绍微服务是基于Spring Cloud框架搭建的,Spring Cloud Config作为服务配置核心。 业务服务只配置服务名称、启用环境和config的URL地址,其余都配置在配置核心,例如服务端口、服务注册核心地址等。可在开发环境(dev)、测试环境(test)和生产环境(prod)别离配置。 所以料想的启动流程是:先加载配置文件,再启动服务。 之前的做法是,将配置文件名称改为:bootstrap.properties。 问题之前间接就能够用,而当初,启动的端口是8080,显著没有加载到bootstrap.properties文件,我认为我的文件名字写错了,核查了几次,确认无误,我猜测预计是bootstramp.properties配置文件没有失效。 之前的版本: spring boot 2.3.1.RELEASE spring cloud Hoxton.SR4 以后版本: spring boot 2.4.2 spring cloud 2020.0.1 查找起因依据下面呈现的问题,我应用百度搜寻了下,大略的起因晓得了:从Spring Boot 2.4版本开始,配置文件加载形式进行了重构。 另外也有配置的默认值变动,如下: Spring Boot 2.3.8.RELEASE package org.springframework.cloud.bootstrap;public class BootstrapApplicationListener implements ApplicationListener<ApplicationEnvironmentPreparedEvent>, Ordered { public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) { ConfigurableEnvironment environment = event.getEnvironment(); if ((Boolean)environment.getProperty("spring.cloud.bootstrap.enabled", Boolean.class, true)) {Spring Boot 2.4.2 package org.springframework.cloud.util;public abstract class PropertyUtils { public static boolean bootstrapEnabled(Environment environment) { return (Boolean)environment.getProperty("spring.cloud.bootstrap.enabled", Boolean.class, false) || MARKER_CLASS_EXISTS; }传统解决方案其实官网说得很明确。看上面这段: ...

February 6, 2021 · 2 min · jiezi

关于springcloud:SpringCloud-Eureka的使用

什么是EurekaEureka是Netfilx开源的一个用来实现微服务的注册与发现的组件。它蕴含Server和Client两局部。 为什么要有Eureka例如目前有两个服务别离为服务A,服务B,咱们能够在服务A调用服务B的接口地址实现调用,然而当服务间的调用关系简单起来的时候,比方服务A还须要调用服务CDE,那么服务A须要保护它调用的所有服务的地址,一旦地址的变更都须要手动去批改。当应用了Eureka这样的服务治理框架后,服务ABCDE能够一起注册到EurekaServer服务上,间接通过服务名来调用其余服务。 Eureka的应用通过Eureka,实现消费者服务80通过服务名调用服务提供者8001的接口。 cloud-eureka-server7001要害代码引入server依赖: <!--eureka-server--><dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></dependency>server端配置: eureka: instance: hostname: localhost client: register-with-eureka: false #false示意不向注册核心注册本人。 fetch-registry: false #false示意本人端就是注册核心,我的职责就是保护服务实例,并不需要去检索服务 service-url: #集群指向其它eureka defaultZone: http://eureka7002.com:7002/eureka/ #单机就是7001本人 defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/启动类注解: @SpringBootApplication@EnableEurekaServerpublic class EurekaMain7001{ public static void main(String[] args) { SpringApplication.run(EurekaMain7001.class, args); }}cloud-provider-payment8001要害代码引入client依赖: <!--eureka-client--><dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency>client端配置: eureka: client: #示意是否将本人注册进EurekaServer默认为true。 register-with-eureka: true #是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true能力配合ribbon应用负载平衡 fetchRegistry: true service-url: defaultZone: http://localhost:7001/eureka启动类注解: @SpringBootApplication@EnableEurekaClientpublic class PaymentMain8001 { public static void main(String[] args) { SpringApplication.run(PaymentMain8001.class, args); }}cloud-consumer-order80要害代码同服务提供者通过服务名调用其余服务的接口(RestTemple记得要加@LoadBalanced,否则找不到服务名): public static final String PAYMENT_URL = "http://CLOUD-PAYMENT-SERVICE";@GetMapping("/consumer/payment/get/{id}")public CommonResult<Payment> getPayment(@PathVariable("id") Long id){ return restTemplate.getForObject(PAYMENT_URL+"/payment/get/"+id,CommonResult.class);} ...

January 16, 2021 · 1 min · jiezi

关于springcloud:用docker部署mysqlredis和nacos

开发Spring Cloud Alibaba微服务利用时,mysql、redis和nacos要先搭建好,本文应用docker搭建; nacos有多种部署形式,见官网文档:nacos docker,这里用的是单机模式mysql模式,所以会与mysql会有关联; docker-compose.yaml定义文件如下: version: "3.6"services: mysql: image: mysql:${MYSQL_VERSION} container_name: mysql ports: - "${MYSQL_HOST_PORT}:3306" volumes: - ${MYSQL_CONF_FILE}:/etc/mysql/conf.d/mysql.cnf:ro - ${MYSQL_DATA_DIR}:/var/lib/mysql/:rw restart: on-failure networks: - default environment: MYSQL_ROOT_PASSWORD: "${MYSQL_ROOT_PASSWORD}" TZ: Asia/Shanghai redis: image: redis:${REDIS_VERSION} container_name: redis environment: TZ: Asia/Shanghai volumes: - ${REDIS_LOG_DIR}:/var/log/redis/:rw - ${REDIS_CONF_FILE}:/usr/local/etc/redis/redis.conf:ro - ${REDIS_DIR}:/var/lib/redis/6379/:rw command: - /usr/local/etc/redis/redis.conf restart: on-failure networks: - default ports: - "${REDIS_HOST_PORT}:6379" nacos: image: nacos/nacos-server:${NACOS_VERSION} container_name: nacos environment: - "PREFER_HOST_MODE=${PREFER_HOST_MODE}" - "MODE=${MODE}" - "SPRING_DATASOURCE_PLATFORM=${SPRING_DATASOURCE_PLATFORM}" - "MYSQL_SERVICE_HOST=${MYSQL_SERVICE_HOST}" - "MYSQL_SERVICE_DB_NAME=${MYSQL_SERVICE_DB_NAME}" - "MYSQL_SERVICE_PORT=${MYSQL_SERVICE_PORT}" - "MYSQL_SERVICE_USER=${MYSQL_SERVICE_USER}" - "MYSQL_SERVICE_PASSWORD=${MYSQL_SERVICE_PASSWORD}" volumes: - ${NACOS_LOG_DIR}:/home/nacos/logs:rw - ${NACOS_PROPERTIES}:/home/nacos/init.d/custom.properties depends_on: - mysql ports: - 8848:8848 restart: on-failure networks: default: 环境变量.env: ...

January 11, 2021 · 2 min · jiezi

关于springcloud:SpringCloud-Alibaba微服务实战二十三-Feign-性能调优

概述在失常状况下Feign有三种客户端实现: Client.Default类:默认的 feign.Client 客户端实现类,外部应用HttpURLConnnection 实现HTTP URL申请解决;ApacheHttpClient 类:外部应用Apache httpclient开源组件实现HTTP URL申请解决的feign.Client 客户端实现类;OkHttpClient类:外部应用OkHttp3 开源组件实现HTTP URL申请解决的feign.Client 客户端实现类。`@ConditionalOnClass({ ILoadBalancer.class, Feign.class })``@ConditionalOnProperty(value = "spring.cloud.loadbalancer.ribbon.enabled",` `matchIfMissing = true)``@Configuration(proxyBeanMethods = false)``@AutoConfigureBefore(FeignAutoConfiguration.class)``@EnableConfigurationProperties({ FeignHttpClientProperties.class })``@Import({ HttpClientFeignLoadBalancedConfiguration.class,` `OkHttpFeignLoadBalancedConfiguration.class,` `DefaultFeignLoadBalancedConfiguration.class })``public class FeignRibbonClientAutoConfiguration {` `...``}`在后面一节内容中咱们看到Feign默认客户端实现 HttpURLConnnection性能不是很好,与Dubbo RPC的性能相差很大。基于 HttpURLConnnection的测试后果如下: 本章内容咱们须要对Feign的所有客户端进行性能测试,以此来确定抉择一个最优的客户端调用工具。 测试工具测试服务器:Intel Core i5-7200U CPU @ 2.50GHz 2.70GHz  6核 16G内存 测试工具:JMeter5.1 线程数:1000 Ramp-Up : 10 JMeter测试工具 「ps : 本文中呈现的所有性能测试后果我都至多测试过10遍以上,最初选取的是一个绝对均匀的后果,测试后果绝对还是比拟精确的。」 HttpClient首先咱们先将客户端工具切换到HttpClient,查看HttpClientFeignLoadBalancedConfiguration配置类,源码如下 `@Configuration(proxyBeanMethods = false)``@ConditionalOnClass(ApacheHttpClient.class)``@ConditionalOnProperty(value = "feign.httpclient.enabled", matchIfMissing = true)``@Import(HttpClientFeignConfiguration.class)``class HttpClientFeignLoadBalancedConfiguration {` `@Bean` `@ConditionalOnMissingBean(Client.class)` `public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory,` `SpringClientFactory clientFactory, HttpClient httpClient) {` `ApacheHttpClient delegate = new ApacheHttpClient(httpClient);` `return new LoadBalancerFeignClient(delegate, cachingFactory, clientFactory);` `}``}`从代码 @ConditionalOnClass({ApacheHttpClient.class})注解可知,只须要在pom文件上加上 HttpClient依赖即可。另外须要在配置文件中配置 feign.httpclient.enabled为 true,从@ConditionalOnProperty注解可知,这个配置能够不写,因为在默认状况下就为true。 所以要应用HttpClient咱们只须要在消费者模块 order-service引入httpclient依赖即可: `<dependency>` `<groupId>io.github.openfeign</groupId>` `<artifactId>feign-httpclient</artifactId>``</dependency>`测试后果 在高并发下性能测试竟然比不过原生的 HttpURLConnnection ,有点点悲观! OkHttp同样先查看okhttp的配置类 OkHttpFeignLoadBalancedConfiguration ...

January 6, 2021 · 1 min · jiezi

关于spring-cloud:changgou

谬误整顿解决:com.sun.jersey.api.client.ClientHandlerException: java.net.ConnectException: Connection refused:解决方案此利用为注册核心,false:不向注册核心注册本人。eureka.client.register-with-eureka=false注册核心职责是保护服务实例,false:不检索服务。eureka.client.fetch-registry=false

January 5, 2021 · 1 min · jiezi

关于spring-cloud:服务链路追踪Spring-Cloud-Sleuth-zpkin-初试

sleuth引入sleuth依赖<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-sleuth</artifactId></dependency>#是否开启sleuth spring.sleuth.enabled=true@ 展现成果 zpkin增加zpkin依赖<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zipkin</artifactId></dependency>配置# 开启Sleuthspring.sleuth.enabled=true#指定zipkin server的地址,上报追踪日志spring.zipkin.base-url=http://localhost:9411# 采样率 越大采集率越高spring.sleuth.sampler.probability=1启动zpkin-serverjava -jar ipkin-server-2.12.9-exec.jar如果要将数据存储到elasticsearch中java -DSTORAGE_TYPE=elasticsearch -DES_HOSTS=http://localhost:9200 -jar zipkin-server-2.12.9-exec.jarSTORAGE_TYPE用于指定Zipkin的存储类型,这里为elasticsearchES_HOSTS 则用于指定Elasticsearch服务器地址列表,有多个节点时应用逗号分隔 如果存在elasticsearch,想查看依赖

December 29, 2020 · 1 min · jiezi

关于springcloud:spring-cloud学习

December 24, 2020 · 0 min · jiezi

关于spring-cloud:Spring-Cloud-202000正式发布再见了Netflix

分享、成长,回绝浅藏辄止。关注公众号【BAT的乌托邦】,回复关键字专栏有Spring技术栈、中间件等小而美的原创专栏供以收费学习。本文已被 https://www.yourbatman.cn 收录。✍前言你好,我是YourBatman。 北京工夫2020-12-22深夜,Spring Cloud 2020.0.0版本正式公布。2020.0.0是第一个应用新版本计划的Spring Cloud发行版本。 对于版本号这里啰嗦几句:在这之前,Spring Cloud的Release Train名称采纳的是伦敦地铁站命名形式,如:Hoxton、Greenwich等。 阐明:2020.0.0版本又名Ilford(地铁站名),因为此我的项目3月后才依照新规更名,预计是为了团队内沟通不便吧,你也能够了解为它仅是一个外部代号而已,不便沟通虽依照字母表顺序排列,但仍存在两个致命问题: 对非英语母语国家(比方天朝)十分不敌对,无奈疾速理清版本号关系A-Z,假使版本号到Z了呢?如何持续倒退?你品,你细品 Spring团队意识到了这确实是个问题,因而在往年3月份作出了扭转。详情参考我后面写的一篇文章(强烈建议每个进来的你都理解下这次规定变更):Spring扭转版本号命名规定:此举对非英语国家很敌对 阐明:版本号规定变更实用于所有Spring技术栈,蕴含Spring Framework、Spring Boot、Spring Cloud、Spring Data...文归正传。Spring Cloud早在年初就启动了该版本的研发工作,并在往年4月份就曾经公布了其2020.0.0-M1版本(第一个里程碑版本),直到离2020年完结不到10天了才“憋出”大招,正式RELEASE。 Spring Cloud作为构建在Spring Boot之上的云计算框架,我感觉本次难产的起因次要有二: Spring Boot 2.4.0版本2020-11-12才正式RELEASE(Spirng Framework 5.3.0版本2020-10-27才RELEASE) Spring Framework 5.3.0正式公布,在云原生路上持续发力Spring Boot 2.4.0正式公布,全新的配置文件加载机制(不向下兼容)改变的确太大,研发、测试、文档编写工作量都是微小的从Spring Framework、Spring Boot、Spring Cloud三者的发版线路图再一次验证了我的那句话:你对Spring Cloud多理解源自于你对Spring Boot有多理解,你对Spring Boot多理解源自于你对Spring Framework有多理解。这就是为何我文章花大量笔墨在Spring Framework上而非Spring Boot上的根本原因,底层通透了,下层运用自如。 版本约定Spring Framework:5.3.2Spring Boot:2.4.1Spring Cloud:2020.0.0 以上版本为SC“携带”的版本 ✍注释有个乏味的景象,截止稿前(2020-12-23 22:00:00)官网还并未同步标注好以后最新版本为2020.0.0版(如图): 其实早在24h之前官网博客就做出了发版宣告: 并且Maven地方仓库也已存在最新Jar包(证实你失常引包、应用是没问题的了): 其实,文档层面不止官网这一处没有sync最新版本,我就不一一例举,毕竟不太重要。针对此景象我yy一下,是不是Spring Cloud团队缺人人手不够用呢?请问社招吗?O(∩_∩)O哈哈~ Spring Cloud版本治理版本治理对于软件开发来说太重要,在Spring Boot呈现之前依赖关系、版本治理让人着实头大(即便有Spring BOM存在),特地是当呈现版本不适配时很容易就偷走你一下午甚至一整天的工夫。 Spring Cloud作为下层利用框架,底层版本匹配了能力失常work,其中最次要就是和Spring Boot的版本号要对齐。 与Spring Boot版本对应关系Spring Boot的呈现和风行大大缓解了上述些状况,但应用起Spring Cloud时它和Spring Boot的版本对应关系仍旧是须要特地关注的。为此我帮你总结出了这个表格: ...

December 24, 2020 · 2 min · jiezi

关于springcloud:SpringCloud项目pomxml配置

上篇说了SpringCloud我的项目目录的搭建,本篇着重形容我的项目pom.xml等其余文件的配置首先申明,本我的项目整体用的是SpringCloud+SpringBoot+Mybatis-plus框架根我的项目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><groupId>org.example</groupId><artifactId>auxiliaryMonitoring</artifactId><version>1.0-SNAPSHOT</version><name>auxiliaryMonitoring</name><!--子模块工厂配置--><modules> <module>consumer</module><!--客户端--> <module>eureka-server</module><!--注册核心--> <module>provider</module><!--业务/数据处理--> <module>system</module><!--系统配置--></modules><!--Spring Boot配置--><parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.4.0</version> <relativePath/> <!-- lookup parent from repository --></parent><!--配置参数--><properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <spring-cloud.version>Dalston.SR1</spring-cloud.version></properties><dependencies> <!--Spring Boot 执行器组件--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!--Spring Cloud 服务注册组件--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka-server</artifactId> </dependency> <!--Spring Boot Web组件--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--Spring Boot 测试组件--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency></dependencies><!--Spring Cloud 版本序列配置--><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><!--仓库配置--><repositories> <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></project>次要是Spring Cloud 服务注册组件、Spring Boot 测试组件、Spring Cloud 版本序列配置、仓库配置等 ...

December 17, 2020 · 2 min · jiezi

关于springcloud:SpringCloud六Config

config 配置核心 yml 配置文件保留到 git 服务器,例如 github.com 或 gitee.com 微服务启动时,从服务器获取配置文件 github 上寄存配置文件新建 “Project”,命名为 config 将sp02,sp03,sp04,sp11四个我的项目的yml配置文件,复制到config我的项目,并改名item-service-dev.ymluser-service-dev.ymlorder-service-dev.ymlzuul-dev.yml最初,清空四个我的项目中的application.yml文件 禁止配置核心的配置信息笼罩客户端配置默认配置核心配置优先级高,配置核心配置会笼罩客户端的所有配置,包含命令行参数配置,这样咱们在item-service和order-service中配置的端口号启动参数会有效 item-service 启动参数: --service.port=8001--service.port=8002order-service 启动参数 --service.port=8201--service.port=8202能够设置禁止配置核心的配置将客户端配置笼罩掉,这样当咱们从控制中心拉取配置文件后,本地的配置会笼罩拉去来的配置在四个配置文件中增加上面的配置 spring: ...... cloud: config: override-none: true筹备仓库新建module: config,当做一个文件夹,用来寄存配置文件把 2,3,4,11 我的项目的配置文件,放到 config 文件夹springcloud1 工程目录创立本地仓库 VCS - Import into version control - Create git repository抉择 springcloud1 工程目录设置老本地仓库把本地仓库提交推送到gitee近程仓库 ctrl + k 或 VCS - commit勾选要提交的文件,填写提交信息,点击提交ctrl+shift+k 或 VCS - git - push点击左上角 define remoteConfig 服务器config 配置核心从 git 下载所有配置文件。而其余微服务启动时从 config 配置核心获取配置信息。 ...

December 3, 2020 · 2 min · jiezi

关于springcloud:SpringCloud四FeignTurbine

Feign集成工具(性能整合) 近程调用:申明式客户端ribbon 负载平衡和重试hystrix 降级和熔断feign 申明式客户端接口微服务利用中,ribbon 和 hystrix 总是同时呈现,feign 整合了两者,并提供了申明式消费者客户端 用 feign 代替 hystrix+ribbon只须要申明一个形象接口,就能够通过接口做近程调用,不须要再应用 RestTemplate 来调用 // 调用近程的商品服务,获取订单的商品列表// 通过注解,配置:// 1. 调用哪个服务// 2. 调用服务的哪个门路// 3. 向门路提交什么参数数据@FeignClient(name="item-service")public interface ItemClient { @GetMapping("/{orderId}") JsonResult<List<Item>> getItems(@PathVariable String orderId);}在这里应用 @GetMapping("/{orderId}"), 指定的是向近程服务调用的门路 新建 sp09-feign 我的项目 pom.xml须要增加 sp01-commons 依赖application.ymlspring: application: name: feign server: port: 3001 eureka: client: service-url: defaultZone: http://eureka1:2001/eureka, http://eureka2:2002/eureka主程序增加 @EnableDiscoveryClient 和 @EnableFeignClientspackage cn.tedu.sp09;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.client.discovery.EnableDiscoveryClient;import org.springframework.cloud.openfeign.EnableFeignClients;@EnableFeignClients@EnableDiscoveryClient@SpringBootApplicationpublic class Sp09FeignApplication { public static void main(String[] args) { SpringApplication.run(Sp09FeignApplication.class, args); }}feign 申明式客户端feign 利用了相熟的 spring mvc 注解来对接口办法进行设置,升高了咱们的学习老本。通过这些设置,feign能够拼接后盾服务的拜访门路和提交的参数例如: ...

December 2, 2020 · 5 min · jiezi

关于springcloud:SpringCloud三Hystrix

Hystrix 断路器零碎容错工具 降级 调用近程服务失败(宕机、500错、超时),能够降级执行以后服务中的一段代码,向客户端返回后果疾速失败熔断 当拜访量过大,呈现大量失败,能够做过热爱护,断开近程服务不再调用限流避免故障流传、雪崩效应https://github.com/Netflix/Hystrix/wiki Hystrix降级hystrix依赖启动类增加注解 @EnableCircuitBreaker增加降级代码// 当调用近程服务失败,跳转到指定的办法,执行降级代码@HystrixCommand(fallbackMethod="办法名")近程调用办法() { restTemplate.getForObject(url,......);}微服务宕机时,ribbon 无奈转发申请敞开 user-service 和 order-service阐明:这是没有hystrix的状况,下来测试hystrix提供的降级解决形式 复制 sp06-ribbon 我的项目,命名为sp07-hystrix抉择 sp06-ribbon 我的项目,ctrl-c,ctrl-v,复制为sp07-hystrix敞开 sp06-ribbon 我的项目,后续测试应用 sp07-hystrix 我的项目 批改 pom.xml 增加 hystrix 起步依赖`<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId></dependency>` 批改 application.yml spring: application: name: hystrix server: port: 3001 eureka: client: service-url: defaultZone: http://eureka1:2001/eureka, http://eureka2:2002/eureka ribbon: MaxAutoRetries: 1 MaxAutoRetriesNextServer: 2 OkToRetryOnAllOperations: true主程序增加 @EnableCircuitBreaker 启用 hystrix 断路器启动断路器,断路器提供两个外围性能: 降级,超时、出错、不可达到时,对服务降级,返回错误信息或者是缓存数据熔断,当服务压力过大,谬误比例过多时,熔断所有申请,所有申请间接降级能够应用 @SpringCloudApplication 注解代替三个注解package cn.tedu.sp06;import org.springframework.boot.SpringApplication;import org.springframework.cloud.client.SpringCloudApplication;import org.springframework.cloud.client.loadbalancer.LoadBalanced;import org.springframework.context.annotation.Bean;import org.springframework.http.client.SimpleClientHttpRequestFactory;import org.springframework.web.client.RestTemplate;//@EnableCircuitBreaker//@EnableDiscoveryClient//@SpringBootApplication@SpringCloudApplicationpublic class Sp06RibbonApplication { @LoadBalanced @Bean public RestTemplate getRestTemplate() { SimpleClientHttpRequestFactory f = new SimpleClientHttpRequestFactory(); f.setConnectTimeout(1000); f.setReadTimeout(1000); return new RestTemplate(f); //RestTemplate 中默认的 Factory 实例中,两个超时属性默认是 -1, //未启用超时,也不会触发重试 //return new RestTemplate(); } public static void main(String[] args) { SpringApplication.run(Sp06RibbonApplication.class, args); }}RibbonController 中增加降级办法为每个办法增加降级办法,例如 getItems() 增加降级办法 getItemsFB()增加 @HystrixCommand 注解,指定降级办法名package cn.tedu.sp06.controller;import cn.tedu.sp01.pojo.Item;import cn.tedu.sp01.pojo.Order;import cn.tedu.sp01.pojo.User;import cn.tedu.web.util.JsonResult;import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.*;import org.springframework.web.client.RestTemplate;import java.util.List;@RestController@Slf4jpublic class RibbonController { @Autowired private RestTemplate restTemplate; @HystrixCommand(fallbackMethod = "getItemsFB") //指定降级办法的办法名 @GetMapping("/item-service/{orderId}") public JsonResult<List<Item>> getItems(@PathVariable String orderId){ //近程调用商品服务 //http://localhost:8001/{orderId} //{1} -- RestTemplate 定义的一种占位符格局,传递参数orderId //return restTemplate.getForObject("http://localhost:8001/{1}",JsonResult.class,orderId); return restTemplate.getForObject("http://item-service/{1}",JsonResult.class,orderId);//Ribbon的形式,将ip:port改为服务名称 } @HystrixCommand(fallbackMethod = "decreaseNumberFB") //指定降级办法的办法名 @PostMapping("/item-service/decreaseNumber") public JsonResult<?> decreaseNumber(@RequestBody List<Item> items){ return restTemplate.postForObject("http://item-service/decreaseNumber", items, JsonResult.class); } // ----------------------- @HystrixCommand(fallbackMethod = "getUserFB") //指定降级办法的办法名 @GetMapping("/user-service/{userId}") public JsonResult<User> getUser(@PathVariable Integer userId){ return restTemplate.getForObject("http://user-service/{1}", JsonResult.class,userId); } @HystrixCommand(fallbackMethod = "addScoreFB") //指定降级办法的办法名 @GetMapping("/user-service/{userId}/score") public JsonResult<?> addScore(@PathVariable Integer userId,Integer score){ return restTemplate.getForObject("http://user-service/{1}/score?score={2}", JsonResult.class,userId,score); } @HystrixCommand(fallbackMethod = "getOrderFB") //指定降级办法的办法名 @GetMapping("/order-service/{orderId}") public JsonResult<Order> getOrder(@PathVariable String orderId){ return restTemplate.getForObject("http://order-service/{1}", JsonResult.class,orderId); } @HystrixCommand(fallbackMethod = "addOrderFB") //指定降级办法的办法名 @GetMapping("/order-service/") public JsonResult<?> addOrder(){ return restTemplate.getForObject("http://order-service/", JsonResult.class); } // ----------------------- //降级办法的参数和返回值,须要和原始办法统一,办法名任意 public JsonResult<List<Item>> getItemsFB(String orderId){ return JsonResult.err("获取订单商品列表失败"); } public JsonResult<?> decreaseNumberFB(List<Item> items){ return JsonResult.err("更新商品库存失败"); } public JsonResult<User> getUserFB(Integer userId){ return JsonResult.err("获取用户信息失败"); } public JsonResult<?> addScoreFB(Integer userId,Integer score){ return JsonResult.err("减少用户积分失败"); } public JsonResult<Order> getOrderFB(String orderId){ return JsonResult.err("获取订单失败"); } public JsonResult<?> addOrderFB(){ return JsonResult.err("增加订单失败"); }}hystrix 超时设置hystrix.command.default.execution.isolation.thread.timeoutInMillisecondshystrix期待超时后, 会执行降级代码, 疾速向客户端返回降级后果, 默认超时工夫是1000毫秒为了测试 hystrix 降级,咱们把 hystrix 期待超时设置得十分小(1000毫秒)此设置个别应大于 ribbon 的重试超时时长,例如 10 秒 ...

December 2, 2020 · 3 min · jiezi

关于spring-cloud:zuul如果两个filter的order一样是如何排序的

最近有个网友问了一个问题,zuul中如果两个filter的order一样,是如何排序的?引起了我的趣味,特地去浏览了它的源码。 如果你有应用过springcloud应该据说过zuul,它的定位是散布式微服务中的API网关服务,当然前面可能要被gateway代替了。zuul是一个L7应用程序网关,提供了动静路由,监督,弹性,安全性等性能。zuul的大部分性能是通过filter实现的。 zuul定义了四种不同生命周期的filter 为了不便操作,zuul内置了一些filter,这些filter次要通过@EnableZuulServer和@EnableZuulProxy注解开启相干性能。@EnableZuulServer注解开启的filter性能如下: @EnableZuulProxy注解除了开启下面这些filter性能之外,还开启了如下的性能: 只需继承ZuulFilter类,实现它的filterType、filterOrder、shouldFilter 和 run办法即可,具体实现可参考如下代码: public class LogFilter extends ZuulFilter { @Override public String filterType() { return FilterConstants.PRE_TYPE; } @Override public int filterOrder() { return 1; } @Override public boolean shouldFilter() { return RequestContext.getCurrentContext().sendZuulResponse(); } @Override public Object run() throws ZuulException { RequestContext currentContext = RequestContext.getCurrentContext(); HttpServletRequest request = currentContext.getRequest(); log.info("zuul pre filter-->" + request.getRequestURL() + "-->" + request.getMethod()); return null; }}下面的四个办法有哪些作用呢? ...

November 25, 2020 · 1 min · jiezi

关于springcloud:Spring-Cloud-Security-OAuth20-认证授权

世界上最快的捷径,就是好高鹜远,本文已收录【架构技术专栏】关注这个喜爱分享的中央。前序最近想搞下基于Spring Cloud的认证受权平台,总体想法是能够对服务间受权,想做一个基于Agent 的无侵入的形式。 因为新版本的Spring Cloud Security 、 OAuth2.0 貌似改了些货色,说上网轻易翻翻,但发现没有针对Spring Security OAuth2.0认证受权系统性的文章。 遂联合一些材料和本人的一些梳理,来搞一个认证受权系列,就当是一个总结了。 其实后面我也搞了几个对于认证受权的文章,但总感觉太系统了,不成体系,没搞过 Security 、OAuth2.0、JWT的人会一脸懵逼。 这次筹备再从头梳理下这方面的只是,逐渐递进。尽量不搞简明扼要,看的脑阔疼,争取一篇一个点的推动。 话不多说,饭要一口口吃,根底的货色其实也很重要,那就从头来说吧。 根底概念1、认证的概念在这个挪动时代,咱们每天都在各种APP间切换着,比方抖音、淘宝、微信等,比方咱们拿抖音来举例说明认证的一些根底概念。 比方咱们在应用抖音前都须要进行注册吧,而后在输出用户名和明码(或验证码)来登录账号。 这里登陆的过程就是 认证 那为什么要认证? 认证,其实就是为了爱护零碎的资源,只有用户身份非法才能够拜访资源。 认证 :用户认证就是判断一个用户的身份是否非法的过程,用户去拜访系统资源时零碎要求验证用户的身份信 息,身份非法方可持续拜访,不非法则回绝拜访。 常见的用户身份认证形式有: 用户名明码登录二维码登录手机短信登录指纹认证人脸识别2、会话的概念大家想想,如果我应用微信每点一个按钮都要我进行一次认证,那我岂不是要疯了。所以为了防止这种问题,在用户认证实现后可将用户信息保留在会话中。 会话其实就是零碎保留了以后用户登录状态所提供的一种机制。 常见的会话形式: 基于session基于token基于session的认证形式: 1、用户认证胜利,在服务端将用户信息保留在session中(目前很多为redis) 2、将sesssion_id返回给客户端并存入 cookie 中 客户端每次申请时带上session_id,服务端就会依据其进行用户合法性验证。当用户退出零碎或session过期时,客户端的session_id也就生效了。 基于token的认证形式: 1、用户认证胜利,在服务端会依据用户信息和某种加密伎俩生产一个token(如JWT)发给客户端 2、客户端将token存入 cookie 或 localStorage 中,在每次申请时带上token,服务端就能够依据token进行用户身份认证。服务端无需进行token存储,因为用户信息都蕴含在token中。 留神: session的认证形式由Servlet标准定制,服务端需存储session,客户端须要反对 cookie(如不反对cookie就须要非凡解决)token的认证形式不须要服务端存储token,并且不限度客户端的存储形式在现今的互联网时代,零碎多为前后端拆散的架构设计,所以基于token的形式更好点3、受权的概念咱们那微信来举例,当用户登陆胜利后就能够应用发朋友圈、增加好友、发红包等性能。 但此时如果咱们没有绑卡,是无奈应用发红包性能的,也就是说咱们没有发红包的权限。 只有绑定银行卡的用户才能够发红包,也就是说此时的用户领有了发红包的权限。 这个依据用户的权限来管制用户应用资源的过程就是受权 。 为什么要受权? 认证是为了确认用户的合法性,而受权是为了更细粒度的对数据进行划分,受权是产生在认证实现后的,用来管制不同的用户拜访不同的资源。 受权: 受权是用户认证通过依据用户的权限来管制用户拜访资源的过程,领有资源的拜访权限则失常拜访,没有 权限则回绝拜访。 受权的数据模型 都晓得写代码有设计模式,通过总结,受权也有其数据模型 其实也就是哪些用户,领有哪些权限,能够拜访哪些资源,如下图: 对于上图,咱们能够形象出几个关键点: who 对what 进行 how 操作 who : 用户 ...

November 23, 2020 · 1 min · jiezi

关于springcloud:Spring-Cloud-学习三Consul服务注册与发现

Consul是一套开源的分布式服务发现和配置管理系统,由HashiCorp公司用Go语言开发。1、概述Consul提供了微服务零碎中的服务治理、配置核心、管制总线等性能。这些性能中的每一个都能够依据须要独自应用,也能够一起应用以构建全方位的服务网络,总之Consul提供了一种残缺的服务网络解决方案。它具备很多长处,包含:基于raft协定,比拟简洁;反对健康检查,同时反对HTTP和DNS协定反对跨数据中心的WAN集群 提供图形界面,跨平台,反对linux,mac,windows。 2、装置并运行consulhttps://www.consul.io/downloa...,下载实现后,解压会呈现consul.exe文件,在cmd下进入consul目录 拜访http://localhost:8500就能够看见consul的界面 3、应用办法新建cloud-providerconsul-payment8006模块pom.xml <dependencies> <dependency><!-- 援用本人定义的api通用包,能够应用Payment领取Entity --> <groupId>com.yu.springcloud</groupId> <artifactId>cloud-api-commons</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--监控--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!--SpringCloud consul-server--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-consul-discovery</artifactId> </dependency> <!--热部署--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>yml server: port: 8006spring: application: name: consul-provider-payment cloud: consul: host: localhost port: 8500 discovery: service-name: ${spring.application.name}主启动 @SpringBootApplication@EnableDiscoveryClientpublic class PaymentMain8006 { public static void main(String[] args) { SpringApplication.run(PaymentMain8006.class, args); }}controller ...

November 12, 2020 · 1 min · jiezi