首页 文章 精选 留言 我的

精选列表

搜索[springcloud],共1352篇文章
优秀的个人博客,低调大师

SpringCloud中Zuul网关原理及其配置,一篇看懂!

作者:kosamino cnblogs.com/jing99/p/11696192.html 正文 Zuul是spring cloud中的微服务网关。网关:是一个网络整体系统中的前置门户入口。请求首先通过网关,进行路径的路由,定位到具体的服务节点上。 Zuul是一个微服务网关,首先是一个微服务。也是会在Eureka注册中心中进行服务的注册和发现。也是一个网关,请求应该通过Zuul来进行路由。 Zuul网关不是必要的。是推荐使用的。 使用Zuul,一般在微服务数量较多(多于10个)的时候推荐使用,对服务的管理有严格要求的时候推荐使用,当微服务权限要求严格的时候推荐使用。 一、Zuul网关的作用 网关有以下几个作用: 统一入口:未全部为服务提供一个唯一的入口,网关起到外部和内部隔离的作用,保障了后台服务的安全性。 鉴权校验:识别每个请求的权限,拒绝不符合要求的请求。 动态路由:动态的将请求路由到不同的后端集群中。 减少客户端与服务端的耦合:服务可以独立发展,通过网关层来做映射。 二、Zuul网关的应用 1、网关访问方式 通过zuul访问服务的,URL地址默认格式为:http://zuulHostIp:port/要访问的服务名称/服务中的URL 服务名称:properties配置文件中的spring.application.name。 服务的URL:就是对应的服务对外提供的URL路径监听。 2、网关依赖注入 <!--springcloudEurekaClient启动器--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-eureka</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-zuul</artifactId></dependency><!--zuul网关的重试机制,不是使用ribbon内置的重试机制是借助spring-retry组件实现的重试开启zuul网关重试机制需要增加下述依赖--><dependency><groupId>org.springframework.retry</groupId><artifactId>spring-retry</artifactId></dependency> 3、网关启动器 /***@EnableZuulProxy-开启Zuul网关。*当前应用是一个Zuul微服务网关。会在Eureka注册中心中注册当前服务。并发现其他的服务。* Zuul需要的必要依赖是spring-cloud-starter-zuul。*/@SpringBootApplication@EnableZuulProxypublicclassZuulApplication{publicstaticvoidmain(String[]args){SpringApplication.run(ZuulApplication.class,args);}} 4、网关全局变量配置 4.1 URL路径匹配 #URLpattern#使用路径方式匹配路由规则。#参数key结构:zuul.routes.customName.path=xxx#用于配置路径匹配规则。#其中customName自定义。通常使用要调用的服务名称,方便后期管理#可使用的通配符有:*** ?#?单个字符#*任意多个字符,不包含多级路径#**任意多个字符,包含多级路径zuul.routes.eureka-application-service.path=/api/**#参数key结构:zuul.routes.customName.url=xxx# url用于配置符合path的请求路径路由到的服务地址。zuul.routes.eureka-application-service.url=http://127.0.0.1:8080/ 4.2 服务名称匹配 #serviceidpattern通过服务名称路由# key结构:zuul.routes.customName.path=xxx#路径匹配规则zuul.routes.eureka-application-service.path=/api/**# key结构:zuul.routes.customName.serviceId=xxx# serviceId用于配置符合path的请求路径路由到的服务名称。zuul.routes.eureka-application-service.serviceId=eureka-application-service 服务名称匹配也可以使用简化的配置: #simpleserviceidpattern简化配置方案#如果只配置path,不配置serviceId。则customName相当于服务名称。#符合path的请求路径直接路由到customName对应的服务上。zuul.routes.eureka-application-service.path=/api/** 4.3 路由排除配置 #ignoredserviceidpattern#配置不被zuul管理的服务列表。多个服务名称使用逗号','分隔。#配置的服务将不被zuul代理。zuul.ignored-services=eureka-application-service#此方式相当于给所有新发现的服务默认排除zuul网关访问方式,只有配置了路由网关的服务才可以通过zuul网关访问#通配方式配置排除列表。zuul.ignored-services=*#使用服务名称匹配规则配置路由列表,相当于只对已配置的服务提供网关代理。zuul.routes.eureka-application-service.path=/api/**#通配方式配置排除网关代理路径。所有符合ignored-patterns的请求路径都不被zuul网关代理。zuul.ignored-patterns=/**/test/**zuul.routes.eureka-application-service.path=/api/** 4.4 路由前缀配置 #prefixURLpattern前缀路由匹配#配置请求路径前缀,所有基于此前缀的请求都由zuul网关提供代理。zuul.prefix=/api#使用服务名称匹配方式配置请求路径规则。#这里的配置将为:http://ip:port/api/appservice/**的请求提供zuul网关代理,可以将要访问服务进行前缀分类。#并将请求路由到服务eureka-application-service中。zuul.routes.eureka-application-service.path=/appservice/** 5 Zuul网关配置总结 网关配置方式有多种,默认、URL、服务名称、排除|忽略、前缀。 网关配置没有优劣好坏,应该在不同的情况下选择合适的配置方案。扩展:大公司为什么都有API网关?聊聊API网关的作用 zuul网关其底层使用ribbon来实现请求的路由,并内置Hystrix,可选择性提供网关fallback逻辑。使用zuul的时候,并不推荐使用Feign作为application client端的开发实现。毕竟Feign技术是对ribbon的再封装,使用Feign本身会提高通讯消耗,降低通讯效率,只在服务相互调用的时候使用Feign来简化代码开发就够了。而且商业开发中,使用Ribbon+RestTemplate来开发的比例更高。 欢迎关注公众号:Java学习指南,每天阅读Java干货文章。无广告无套路,领取最新的项目实战教程 + 面试资料,筑梦大厂 三、Zuul网关过滤器 Zuul中提供了过滤器定义,可以用来过滤代理请求,提供额外功能逻辑。如:权限验证,日志记录等。 Zuul提供的过滤器是一个父类。父类是ZuulFilter。通过父类中定义的抽象方法filterType,来决定当前的Filter种类是什么。有前置过滤、路由后过滤、后置过滤、异常过滤。 前置过滤:是请求进入Zuul之后,立刻执行的过滤逻辑。 路由后过滤:是请求进入Zuul之后,并Zuul实现了请求路由后执行的过滤逻辑,路由后过滤,是在远程服务调用之前过滤的逻辑。 后置过滤:远程服务调用结束后执行的过滤逻辑。 异常过滤:是任意一个过滤器发生异常或远程服务调用无结果反馈的时候执行的过滤逻辑。无结果反馈,就是远程服务调用超时。 3.1 过滤器实现方式 继承父类ZuulFilter。在父类中提供了4个抽象方法,分别是:filterType, filterOrder, shouldFilter, run。其功能分别是: filterType:方法返回字符串数据,代表当前过滤器的类型。可选值有-pre, route, post, error。 pre - 前置过滤器,在请求被路由前执行,通常用于处理身份认证,日志记录等; route - 在路由执行后,服务调用前被调用; error - 任意一个filter发生异常的时候执行或远程服务调用没有反馈的时候执行(超时),通常用于处理异常; post - 在route或error执行后被调用,一般用于收集服务信息,统计服务性能指标等,也可以对response结果做特殊处理。 filterOrder:返回int数据,用于为同filterType的多个过滤器定制执行顺序,返回值越小,执行顺序越优先。 shouldFilter:返回boolean数据,代表当前filter是否生效。 run:具体的过滤执行逻辑。如pre类型的过滤器,可以通过对请求的验证来决定是否将请求路由到服务上;如post类型的过滤器,可以对服务响应结果做加工处理(如为每个响应增加footer数据)。 3.2 过滤器的生命周期 3.3 代码示例 /*** Zuul过滤器,必须继承ZuulFilter父类。*当前类型的对象必须交由Spring容器管理。使用@Component注解描述。*继承父类后,必须实现父类中定义的4个抽象方法。*shouldFilter、run、filterType、filterOrder*/@ComponentpublicclassLoggerFilterextendsZuulFilter{privatestaticfinalLoggerlogger=LoggerFactory.getLogger(LoggerFilter.class);/***返回boolean类型。代表当前filter是否生效。*默认值为false。*返回true代表开启filter。*/@OverridepublicbooleanshouldFilter(){returntrue;}/*** run方法就是过滤器的具体逻辑。* return 可以返回任意的对象,当前实现忽略。(spring-cloud-zuul官方解释)*直接返回null即可。*/@OverridepublicObjectrun()throwsZuulException{//通过zuul,获取请求上下文RequestContextrc=RequestContext.getCurrentContext();HttpServletRequestrequest=rc.getRequest();logger.info("LogFilter1.....method={},url={}",request.getMethod(),request.getRequestURL().toString());//可以记录日志、鉴权,给维护人员记录提供定位协助、统计性能returnnull;}/***过滤器的类型。可选值有:*pre-前置过滤*route-路由后过滤*error-异常过滤*post-远程服务调用后过滤*/@OverridepublicStringfilterType(){return"pre";}/***同种类的过滤器的执行顺序。*按照返回值的自然升序执行。*/@OverridepublicintfilterOrder(){return0;}} 四、Zuul网关的容错(与Hystrix的无缝结合) 在spring cloud中,Zuul启动器中包含了Hystrix相关依赖,在Zuul网关工程中,默认是提供了Hystrix Dashboard服务监控数据的(hystrix.stream),但是不会提供监控面板的界面展示。可以说,在spring cloud中,zuul和Hystrix是无缝结合的。 4.1 Zuul中的服务降级处理 在Edgware版本之前,Zuul提供了接口ZuulFallbackProvider用于实现fallback处理。从Edgware版本开始,Zuul提供了ZuulFallbackProvider的子接口FallbackProvider来提供fallback处理。 Zuul的fallback容错处理逻辑,只针对timeout异常处理,当请求被Zuul路由后,只要服务有返回(包括异常),都不会触发Zuul的fallback容错逻辑。 因为对于Zuul网关来说,做请求路由分发的时候,结果由远程服务运算的。那么远程服务反馈了异常信息,Zuul网关不会处理异常,因为无法确定这个错误是否是应用真实想要反馈给客户端的。 4.2 代码示例 /***如果需要在Zuul网关服务中增加容错处理fallback,需要实现接口ZuulFallbackProvider*spring-cloud框架,在Edgware版本(包括)之后,声明接口ZuulFallbackProvider过期失效,*提供了新的ZuulFallbackProvider的子接口-FallbackProvider*在老版本中提供的ZuulFallbackProvider中,定义了两个方法。*-StringgetRoute()*当前的fallback容错处理逻辑处理的是哪一个服务。可以使用通配符‘*’代表为全部的服务提供容错处理。*如果只为某一个服务提供容错,返回对应服务的spring.application.name值。*-ClientHttpResponsefallbackResponse()*当服务发生错误的时候,如何容错。*新版本中提供的FallbackProvider提供了新的方法。*-ClientHttpResponsefallbackResponse(Throwablecause)*如果使用新版本中定义的接口来做容错处理,容错处理逻辑,只运行子接口中定义的新方法。也就是有参方法。*是为远程服务发生异常的时候,通过异常的类型来运行不同的容错逻辑。*/@ComponentpublicclassTestFallBbackProviderimplementsFallbackProvider{/*** return -返回fallback处理哪一个服务。返回的是服务的名称*推荐-为指定的服务定义特性化的fallback逻辑。*推荐-提供一个处理所有服务的fallback逻辑。*好处-服务某个服务发生超时,那么指定的fallback逻辑执行。如果有新服务上线,未提供fallback逻辑,有一个通用的。*/@OverridepublicStringgetRoute(){return"eureka-application-service";}/*** fallback逻辑。在早期版本中使用。*Edgware版本之后,ZuulFallbackProvider接口过期,提供了新的子接口FallbackProvider*子接口中提供了方法ClientHttpResponse fallbackResponse(Throwable cause)。*优先调用子接口新定义的fallback处理逻辑。*/@OverridepublicClientHttpResponsefallbackResponse(){System.out.println("ClientHttpResponsefallbackResponse()");List<Map<String,Object>>result=newArrayList<>();Map<String,Object>data=newHashMap<>();data.put("message","服务正忙,请稍后重试");result.add(data);ObjectMappermapper=newObjectMapper();Stringmsg="";try{msg=mapper.writeValueAsString(result);}catch(JsonProcessingExceptione){msg="";}returnthis.executeFallback(HttpStatus.OK,msg,"application","json","utf-8");}/*** fallback逻辑。优先调用。可以根据异常类型动态决定处理方式。*/@OverridepublicClientHttpResponsefallbackResponse(Throwablecause){System.out.println("ClientHttpResponsefallbackResponse(Throwablecause)");if(causeinstanceofNullPointerException){List<Map<String,Object>>result=newArrayList<>();Map<String,Object>data=newHashMap<>();data.put("message","网关超时,请稍后重试");result.add(data);ObjectMappermapper=newObjectMapper();Stringmsg="";try{msg=mapper.writeValueAsString(result);}catch(JsonProcessingExceptione){msg="";}returnthis.executeFallback(HttpStatus.GATEWAY_TIMEOUT,msg,"application","json","utf-8");}else{returnthis.fallbackResponse();}}/***具体处理过程。*@paramstatus 容错处理后的返回状态,如200正常GET请求结果,201正常POST请求结果,404资源找不到错误等。*使用spring提供的枚举类型对象实现。HttpStatus*@paramcontentMsg 自定义的响应内容。就是反馈给客户端的数据。*@parammediaType 响应类型,是响应的主类型,如:application、text、media。*@paramsubMediaType 响应类型,是响应的子类型,如:json、stream、html、plain、jpeg、png等。*@paramcharsetName 响应结果的字符集。这里只传递字符集名称,如:utf-8、gbk、big5等。*@returnClientHttpResponse 就是响应的具体内容。*相当于一个HttpServletResponse。*/privatefinalClientHttpResponseexecuteFallback(finalHttpStatusstatus,StringcontentMsg,StringmediaType,StringsubMediaType,StringcharsetName){returnnewClientHttpResponse(){/***设置响应的头信息*/@OverridepublicHttpHeadersgetHeaders(){HttpHeadersheader=newHttpHeaders();MediaTypemt=newMediaType(mediaType,subMediaType,Charset.forName(charsetName));header.setContentType(mt);returnheader;}/***设置响应体* zuul会将本方法返回的输入流数据读取,并通过HttpServletResponse的输出流输出到客户端。*/@OverridepublicInputStreamgetBody()throwsIOException{Stringcontent=contentMsg;returnnewByteArrayInputStream(content.getBytes());}/***ClientHttpResponse的fallback的状态码返回String*/@OverridepublicStringgetStatusText()throwsIOException{returnthis.getStatusCode().getReasonPhrase();}/***ClientHttpResponse的fallback的状态码返回HttpStatus*/@OverridepublicHttpStatusgetStatusCode()throwsIOException{returnstatus;}/***ClientHttpResponse的fallback的状态码返回int*/@OverridepublicintgetRawStatusCode()throwsIOException{returnthis.getStatusCode().value();}/***回收资源方法*用于回收当前fallback逻辑开启的资源对象的。*不要关闭getBody方法返回的那个输入流对象。*/@Overridepublicvoidclose(){}};}} 五、Zuul网关的限流保护 Zuul网关组件也提供了限流保护。当请求并发达到阀值,自动触发限流保护,返回错误结果。只要提供error错误处理机制即可。 Zuul的限流保护需要额外依赖spring-cloud-zuul-ratelimit组件。 <dependency><groupId>com.marcosbarbero.cloud</groupId><artifactId>spring-cloud-zuul-ratelimit</artifactId><version>1.3.4.RELEASE</version></dependency> 5.1 全局限流配置 使用全局限流配置,zuul会对代理的所有服务提供限流保护。 #开启限流保护zuul.ratelimit.enabled=true#60s内请求超过3次,服务端就抛出异常,60s后可以恢复正常请求zuul.ratelimit.default-policy.limit=3zuul.ratelimit.default-policy.refresh-interval=60#针对IP进行限流,不影响其他IPzuul.ratelimit.default-policy.type=origin 5.2 局部限流配置 使用局部限流配置,zuul仅针对配置的服务提供限流保护。 #开启限流保护zuul.ratelimit.enabled=true# hystrix-application-client服务60s内请求超过3次,服务抛出异常。zuul.ratelimit.policies.hystrix-application-client.limit=3zuul.ratelimit.policies.hystrix-application-client.refresh-interval=60#针对IP限流。zuul.ratelimit.policies.hystrix-application-client.type=origin 5.3 限流参数简介 六、Zuul网关性能调优:网关的两层超时调优 使用Zuul的spring cloud微服务结构图: 从上图中可以看出。整体请求逻辑还是比较复杂的,在没有zuul网关的情况下,app client请求app service的时候,也有请求超时的可能。那么当增加了zuul网关的时候,请求超时的可能就更明显了。 当请求通过zuul网关路由到服务,并等待服务返回响应,这个过程中zuul也有超时控制。zuul的底层使用的是Hystrix+ribbon来实现请求路由。结构如下: zuul中的Hystrix内部使用线程池隔离机制提供请求路由实现,其默认的超时时长为1000毫秒。ribbon底层默认超时时长为5000毫秒。如果Hystrix超时,直接返回超时异常。如果ribbon超时,同时Hystrix未超时,ribbon会自动进行服务集群轮询重试,直到Hystrix超时为止。如果Hystrix超时时长小于ribbon超时时长,ribbon不会进行服务集群轮询重试。 那么在zuul中可配置的超时时长就有两个位置:Hystrix和ribbon。具体配置如下: #开启zuul网关重试zuul.retryable=true#hystrix超时时间设置#线程池隔离,默认超时时间1000mshystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=8000# ribbon超时时间设置:建议设置比Hystrix小#请求连接的超时时间:默认5000msribbon.ConnectTimeout=5000#请求处理的超时时间:默认5000msribbon.ReadTimeout=5000#重试次数:MaxAutoRetries表示访问服务集群下原节点(同路径访问);MaxAutoRetriesNextServer表示访问服务集群下其余节点(换台服务器)ribbon.MaxAutoRetries=1ribbon.MaxAutoRetriesNextServer=1#开启重试ribbon.OkToRetryOnAllOperations=true Spring-cloud中的zuul网关重试机制是使用spring-retry实现的。工程必须依赖下述资源: <dependency><groupId>org.springframework.retry</groupId><artifactId>spring-retry</artifactId></dependency> -往期精彩 - 知乎热议:计算机专业钱景究竟如何? Spring Cloud架构的各个组件的原理分析 面试:什么是 redis 的雪崩、穿透和击穿?redis 崩溃之后会怎么样? 全干货技术公众号Java学习指南👇👇长按上方二维码关注公众号 本文分享自微信公众号 - Java学习指南(gh_85b94beaede2)。如有侵权,请联系 support@oschina.cn 删除。本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

优秀的个人博客,低调大师

SpringCloud微服务(04):Turbine组件,实现微服务集群监控

本文源码:GitHub·点这里 || GitEE·点这里 一、聚合监控简介 1、Dashboard组件 微服务架构中为了保证程序的可用性,防止程序出错导致网络阻塞,出现了断路器模型。断路器的状况反应程序的可用性和健壮性,它是一个重要指标。HystrixDashboard是作为断路器状态的一个组件,提供了数据监控和直观的图形化界面。 2、Turbine组件 Hystrix Dashboard组件监控服务的熔断情况时,每个服务都有图形界面,当微服务数量很多时,监控非常繁杂.为了同时监控多个服务的熔断状况,Netflix开源了Hystrix的另一个组件Turbine.Turbine用于聚合多个Hystrix Dashboard监控,将多个Hystrix Dashboard组件的数据聚集在一个面板展示,集中监控。 3、案例结构 聚合监控服务 node04-monitor-7002 注册中心 node04-eureka-7001 两个服务提供者,都配置了熔断器,和Dashboard组件 node04-provider-6001 node04-provider-6002 二、Dashboard组件 这个组件是针对单个微服务的监控的。具体使用流程如下。 1、注解和依赖 <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId> </dependency> 启动类注解 @EnableHystrix @EnableHystrixDashboard 2、启动下面两个服务 node04-eureka-7001 node04-provider-6001 3、访问指定接口 1)、访问配置的熔断接口http://localhost:6001/getInfo2)、打开数据面板http://localhost:6001/hystrix.stream可以看到一些具体的数据,类似打印日志的方式,展现上面接口的执行信息。3)、打开图形面板http://localhost:6001/hystrix查看配置监控信息。 刷新几次上面配置的熔断接口,查看效果。 三、Turbine组件 node04-monitor-7002 聚合监控服务,聚集6001,和6002两个服务的监控。 1、依赖和注解 1)、服务提供者新增依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> 2)、聚合服务依赖 <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-turbine</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-netflix-turbine</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> 启动类注解 @EnableTurbine 2、启动服务 依次启动注册中心,两个服务提供者,最后启动聚合监控中心。 3、操作流程 1)、打开监控面板进行如下配置 2)、刷新两个服务的熔断接口 http://localhost:6001/getInfo http://localhost:6002/getInfo 查看上面面板的监控信息如下。 聚合监控服务流程就是这样了。 四、源代码说明 GitHub·地址 https://github.com/cicadasmile/spring-cloud-base GitEE·地址 https://gitee.com/cicadasmile/spring-cloud-base

优秀的个人博客,低调大师

整合SpringCloud微服务分布式云架构技术点

spring cloud本身提供的组件就很多,但我们需要按照企业的业务模式来定制企业所需要的通用架构,那我们现在需要考虑使用哪些技术呢? 下面我针对于spring cloud微服务分布式云架构做了以下技术总结,希望可以帮助到大家: View: H5、Vue.js、Spring Tag、React、angularJs Spring Boot/Spring Cloud:Zuul、Ribbon、Feign、Turbine、Hystrix、Oauthor2、Sleuth、API Gateway、Spring Cloud、Config Eureka、SSO、Spring Cloud、BUS、Turbine、Zipkin、Cache、Spring Cloud Admin、API Gateway、ELK Spring Cloud Security、 Spring Cloud Stream Component:RoketMQ、Kafka、MongoDB、OSS、Redis、Swagger、Zuul、Label、BASE、Charts、Utils DAO: Spring Data、Mybatis、OSS、 DTO Data Storage:RDBS DFS、NOSQL/Hadoop Infrastructure:LogBack、BUS、Jenkins、Zipkin、Druid、Swagger、Docker

优秀的个人博客,低调大师

springcloud云服务架构-HongHu commonservice-eureka项目构建过程

上一篇我们回顾了关于 spring cloud eureka的相关基础知识,现在我们针对于HongHu cloud的eureka项目做以下构建,整个构建的过程很简单,我会将每一步都构建过程记录下来,希望可以帮助到大家: <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.ml.honghu</groupId> <artifactId>particle-commonservice</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <artifactId>particle-commonservice-eureka</artifactId> <packaging>jar</packaging> <name>particle-commonservice-eureka</name> <description>particle-commonservice project for Spring Boot</description> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka-server</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <executions> <execution> <id>1</id> <goals> <goal>repackage</goal> </goals> </execution> <execution> <id>2</id> <goals> <goal>build-info</goal> </goals> </execution> </executions> <configuration> <executable>true</executable> </configuration> </plugin> </plugins> </build> </project> 在启动类入口引用eureka的相关配置,代码如下: package com.ml.honghu; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; @EnableEurekaServer @SpringBootApplication public class ServiceApplication { public static void main(String[] args) { SpringApplication.run(ServiceApplication.class, args); } } 3.配置application.yml文件 # server (eureka 默认端口为:8761) server: port: 8761 # spring spring: application: name: particle-commonservice-erueka # eureka eureka: client: # 是否注册到eureka register-with-eureka: true # 是否从eureka获取注册信息 fetch-registry: false availability-zones: honghu: honghuZone service-url: honghuZone: http://honghu:123456@localhost:8761/eureka/ defaultZone: http://honghu:123456@localhost:8761/eureka/ instance: prefer-ip-address: true hostname: localhost metadataMap: zone: honghuZone user: ${security.user.name} password: {security.user.password} # 指定环境 environment: dev #指定数据中心 datacenter: honghu # 关闭自我保护模式 server: enable-self-preservation: false #设置清理无效节点的时间间隔,默认60000,即是60s eviction-interval-timer-in-ms: 60000 # 服务认证 security: basic: enabled: true user: name: honghu password: 123456 management: security: enabled: false 增加项目的log机制和打包运行机制(后面我们会详细编写针对于Linux Centos下的打包部署机制) 自此整个项目部署完成,通过手动方式进行Run As --> Spring Boot App,运行结果如下: 控制台运行结果: 访问控制台并登陆: 控制台运行效果: 从现在开始,我这边会将近期研发的spring cloud微服务云架构的搭建过程和精髓记录下来,帮助更多有兴趣研发spring cloud框架的朋友,

优秀的个人博客,低调大师

第二章:SpringCloud 将微服务注册至Eureka

1.创建eureka模块 image.png 2.添加pom依赖 <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka-server</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-netflix-eureka-server</artifactId> </dependency> 并且加入父依赖管理。 <parent> <groupId>com.laojiao</groupId> <artifactId>fantj-parent</artifactId> <version>0.0.1-SNAPSHOT</version> <relativePath/> <!-- lookup parent from repository --> </parent> 同样在父类版本控制器里添加上这个模块的pom路径。 <modules> <module>../fantj-consumer-movie</module> <module>../fantj-provider-user</module> <module>../fantj-discovery-eureka</module> </modules> 3.配置application.yml server: port: 9000 eureka: client: register-with-eureka: false fetch-registry: false service-url: defaultZone: http://127.0.0.1:9000/eureka 如果想给eureka服务上添加身份验证功能,需要补充 #加入密码验证 security: basic: enabled: true user: name: laojiao password: laojiao 并且还需要添加springsecurity的依赖包。 我在这里不用身份验证。所以忽略该步骤 4.在启动类上加注解 @EnableEurekaServer表示这个springboot是一个eureka服务 启动该模块。 image.png 5.将服务注册至Eureka服务 image.png 比如我要将这个服务注册至eureka。 加依赖 <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> 第一个是eureka的依赖。第二个是监控与管理模块,它可以将该模块运行时的信息暴露出来。详细查看官方文档。 在启动类里加注解@EnableEurekaClient标明它是个eureka客户端 配置application 在原有基础上添加 eureka: client: service-url: defaultZone: http://127.0.0.1:9000/eureka #这个是eureka模块配置的默认空间 instance: prefer-ip-address: true #将主机名改成ip(192.168.0.1) instance-id: ${spring.application.name}:${spring.application.instance_id}:${server.port} instance是修改注册到eureka的ip地址信息。详细查看文档。 启动项目 image.png 我们就看到了user注册到了eureka列表里。

优秀的个人博客,低调大师

springcloud微服务二:Eureka服务治理之服务注册中心

当初步的学习了spring boot,了解了spring boot的基本实现过程后,我就正式开始学习spring cloud,首先就从Eureka服务治理开始。 服务治理包含三个核心的角色:服务注册中心、服务提供者和服务消费者,他们相对独立,新的服务要向服务注册中心注册,新的消费者会向服务注册中心索引服务列表。 一番了解之后,让我想到了人才招聘。在我看来,现在普遍存在的招聘形式也是分为了三个部分:招聘网站或者人才市场、发布招聘需求的企业、需要找工作的人。当然了,也可以把企业和人换一下位置,那就是:招聘网站或者人才市场、找工作的人发布的简历、需要招聘的企业。 那么这里的招聘网站或者人才市场就如同Eureka服务治理中的服务注册中心,不管是企业的招聘需求还是人的简历,都可以看做一种需求的同时看成一种服务。当有了一个这种新的服务或者需求后会发布在网站上或者人才市场,实际上就相当于Eureka服务治理中,新的服务通知注册到服务注册中心。而我们企业查找相关简历,或者找工作的人查找相关的招聘需求,就是客户端向注册中心索引服务。 在这个过程中,招聘网站、企业和找工作的人是各自独立的,由招聘网站把企业和人联系起来,前提就是企业和人知道网站的地址,这就如同在Eureka服务治理的服务提供者和服务消费者的application.properties文件中配置eureka.client.serviceUrl.defaultZone来指定服务注册中心。 有了一点简单的理解之后,就是实际的项目构建,首先需要构建一个基础的spring boot项目作为服务注册中心,勾选web选项,这样会创建一个上一篇结构的项目。然后在pom.xml文件中加入Eureka的以来配置: <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka-server</artifactId> </dependency> 以及如下的dependencyManagement,指定spring cloud的版本: <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Brixton.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> 这里需要注意的是,spring cloud的版本号是以英国伦敦地铁站的名字命名的,按首字母A-Z的顺序排,不同的spring cloud版本相对应的spring boot的版本是有限制的,否则无法使用。 具体的对应需要参考官网说明,目前比较新的spring boot版本是1.5.2,而对应的spring cloud的版本是Dalston,我这里例子中用的是1.3.8的spring boot,因此spring cloud版本是Brixton。 配置好依赖之后,下一步就是在创建项目时自动生成的那个类中加入@EnableEurekaServer注解,来启动一个服务注册中心,如下: @EnableEurekaServer @SpringBootApplication public class EurekaServer1Application { public static void main(String[] args) { SpringApplication.run(EurekaServer1Application.class, args); } } 然后便是在基本的配置文件application.properties中进行一些必要的配置: #应用名,服务名,如果不指定就是unkown spring.application.name=eureka-server #服务端口,实际上就是tomcat端口,浏览器访问或者其他地方调用时需要用的端口 server.port=1000 #实例的主机名 eureka.instance.hostname=server1 #设置是否向注册中心注册,默认是true eureka.client.register-with-eureka=false #是否需要去检索寻找服务,默认是true eureka.client.fetch-registry=false #指定注册中心 eureka.client.serviceUrl.defaultZone=http://server1:1000/eureka/ 就这样,一个简单的Eureka服务注册中心就完成了,除了引入依赖包的配置、properties的基本配置外,就是在代码中加了一个@EnableEurekaServer,非常的简单。 然后浏览其访问localhost:1000或者server1:1000(这里使用主机名需要配置ip和主机的映射)就可以看到如下界面: 如果有新的服务注册到服务注册中心,那么在上图中红框标注的地方就会有所显示,就比如如果我修改application.properties文件,去掉这一段配置: #设置是否向注册中心注册,默认是true eureka.client.register-with-eureka=false #是否需要去检索寻找服务,默认是true eureka.client.fetch-registry=false 那么该服务注册中心就会把自己也当做一个服务注册到这个注册中心中,那么就会如下图所示: 上边所实现的是单机版的服务注册中心,而微服务架构的九大特征之一就是高可用性,也就是需要注册中心从单机模式变为集群模式,使其中某个注册中心出现故障的情况下不影响整个业务系统的运行。 在spring cloud中,这个实现过程就十分的简单,简单到我们只需要在上述的过程中仅仅做一个很小的配置修改就可以了。 一是去掉eureka.client.register-with-eureka=false和eureka.client.fetch-registry=false的配置,使得注册中心可以自己把自己注册为服务,二是在指定注册中心的时候指定所有的注册中心,三是修改端口和主机实例名,修改后的配置如下: spring.application.name=eureka-server server.port=1000 eureka.instance.hostname=server1 eureka.client.serviceUrl.defaultZone=http://server1:1000/eureka/,http://server2:2000/eureka/ 同样的,我们需要在另一个注册中心中把配置文件改为类似下边的样子: spring.application.name=eureka-server server.port=2000 eureka.instance.hostname=server2 eureka.client.serviceUrl.defaultZone=http://server1:1000/eureka/,http://server2:2000/eureka/ 然后我们启动其中一个注册中心后再访问各自的页面,会看到如下所示: 这时候会看到我们的服务注册中心已经成为了集群模式,但是server2是unavailable的,并不可用,而当我们把另一个注册中心server2启动后,就会看到有些内容有了变化,server2也是可用的了,同样的,如果访问server2的页面,会看到这里列出server1的状态。 正常情况来说,两个注册中心是应该在不同的服务器中运行的,这样才能更好的实现高可用,所以就是两套代码。 但是在学习的过程中由于环境的限制,也为了方便,实际上就可以用一套代码,然后弄两个分别代表server1和server2的配置文件就可以了,文件命名需要遵循spring boot的约定规则,然后再application.properties文件中使用spring.profiles.active属性来指定运行的时候需要具体启用的篇配置就可以了,如图:

优秀的个人博客,低调大师

(十一)Java springcloud B2B2C o2o多用户商城 springcloud架构- - SSO单点登录之OAuth2.0登...

上一篇是站在巨人的肩膀上去研究OAuth2.0,也是为了快速帮助大家认识OAuth2.0,闲话少说,我根据框架中OAuth2.0的使用总结,画了一个简单的流程图(根据用户名+密码实现OAuth2.0的登录认证):上面的图很清楚的描述了当前登录login的流程,现在我们针对于login做成相关的微服务,解析如下: 请求方式:POST服务URL:http://localhost:8080/user/login参数类型:application/json Headers: Content-Type: application/json Authorization: Basic QXkjkdkYkhfeyKOKKHUM67ejfjeSfnrRdk5nPT0= Body:{ "userName":"admin", ---也可以是手机号码等 "password": "e10adc3949ba59abbe56e057f20f883e" } 返回值类型: application/json 返回的结果集: { "code": "200", "message": "Success", "version": "v1.0", "data": { "userInfo": { "userId": "00001", "pwd": "e10adc3949ba59abbe56e057f20f883e", "userName": "admin", "mobile": "15875500000", "telephone": "", "wechat": "", "email": "xxx@qq.com", "status": "1", "createTime": "2017-06-26" }, "roleIds": "100", "tokenInfo": { "accessToken":"4de55a69-e372-4766-acd3-1c419d6f2fda", "tokenType": "bearer", "webTokent":"uHSLjfJoQwU4t4PAqCzH1SN0fp7PUWKluPNS+x1dZ8R9Gx+NJkBI7w==", "refreshToken":"d3d71594-5c3f-4a68-a7e5-b8d21c4fa73b", "expiresIn": 34644, "scope": "read write" } } } 备注:可以使用Postman工具进行测试框架设计思想: 提供独立的commonservice-sso的微服务、提供component-sso的依赖组件、提供针对于用户登录的微服务客户端user-service微服务接口。 整个执行的流程如下:user-service ---> commonservice-sso --->component-sso这里还没有讲解到服务网关,后面会涉及到服务网关和sso单点登录之间如何实现服务认证和鉴权。 从现在开始,我这边会将近期研发的spring cloud微服务云架构的搭建过程和精髓记录下来,帮助更多有兴趣研发spring cloud框架的朋友,大家来一起探讨spring cloud架构的搭建过程及如何运用于企业项目。

优秀的个人博客,低调大师

(十二)Java springcloud B2B2C o2o多用户商城 springcloud架构-- SSO单点登录之OAuth2.0 登...

上一篇我根据框架中OAuth2.0的使用总结,画了一个根据用户名+密码实现OAuth2.0的登录认证的流程图,今天我们看一下logout的流程: /** * 用户注销 * @param accessToken * @return */ @RequestMapping(value = "/user/logout", method = RequestMethod.POST) public ResponseVO userLogout(@RequestHeader(value = "accessToken", required = true) String accessToken, @RequestHeader(value = "userId", required = true) Long userId) throws Exception{ OauthAccessToken oauthAccessToken = userMgrService.getOauthAccessToken(accessToken); if(null == oauthAccessToken){ return UserResponseCode.buildEnumResponseVO(UserResponseCode.RESPONSE_CODE_OAUTH_ACCESSTOKEN_EMPTY, null); } //刪除OauthToken记录 boolean result = userMgrService.revokeOauthToken(oauthAccessToken); if(result){ return UserResponseCode.buildEnumResponseVO(UserResponseCode.RESPONSE_RETURN_CODE_SUCCESS, null); } return UserResponseCode.buildEnumResponseVO(UserResponseCode.RESPONSE_CODE_SYSTEM_ERROR, null); } 我这里只是简单写了一些登出的代码,我们会在后面的文章中详细贴出所有代码供大家参考,而且会从创建数据库,到执行操作的每一个流程记录下来。 从现在开始,我这边会将近期研发的spring cloud微服务云架构的搭建过程和精髓记录下来,帮助更多有兴趣研发spring cloud框架的朋友,大家来一起探讨spring cloud架构的搭建过程及如何运用于企业项目。完整项目的源码来源

优秀的个人博客,低调大师

(十三)Java springcloud B2B2C o2o多用户商城 springcloud架构 - SSO单点登录之OAuth2.0 根...

上一篇我根据框架中OAuth2.0的使用总结,画了SSO单点登录之OAuth2.0 登出流程,今天我们看一下根据用户token获取yoghurt信息的流程: /** * 根据token获取用户信息 * @param accessToken * @return * @throws Exception */ @RequestMapping(value = "/user/token/{accesstoken}", method = RequestMethod.GET) public ResponseVO getUserByToken(@PathVariable(value = "accessToken", required = true) String accessToken,@RequestHeader(value = "userId", required = true) Long userId) throws Exception { if(StringUtils.isEmpty(accessToken)){ return UserResponseCode.buildEnumResponseVO(UserResponseCode.RESPONSE_CODE_REQ_CANNOT_EMPTY, null); } OauthAccessToken oauthAccessToken = userMgrService.getOauthAccessToken(accessToken); if(null == oauthAccessToken){ return UserResponseCode.buildEnumResponseVO(UserResponseCode.RESPONSE_CODE_OAUTH_ACCESSTOKEN_EMPTY, null); } String userName = oauthAccessToken.getUserName(); if (StringUtils.isEmpty(userName)) { return UserResponseCode.buildEnumResponseVO(UserResponseCode.RESPONSE_CODE_OAUTH_ACCESSTOKEN_EMPTY, null); } return this.getUser(userName); } @RequestMapping(path = "/user/get/{userName}", method = RequestMethod.GET) public ResponseVO getUser(@PathVariable(value = "userName") String userName) { Map<String, Object> returnData = null; try { User user = userMgrService.getUserByName(userName); if (null != user) { returnData = new HashMap<String, Object>(); returnData.put("user", user); return UserResponseCode.buildEnumResponseVO(UserResponseCode.RESPONSE_CODE_SUCCESS, returnData); } return UserResponseCode.buildEnumResponseVO(UserResponseCode.RESPONSE_CODE_SYSTEM_ERROR, null); } catch (Exception e) { return UserResponseCode.buildEnumResponseVO(UserResponseCode.RESPONSE_CODE_SYSTEM_ERROR, null); } } 我这里只是简单写了一些登出的代码,我们会在后面的文章中详细贴出所有代码供大家参考,而且会从创建数据库,到执行操作的每一个流程记录下来。 从现在开始,我这边会将近期研发的spring cloud微服务云架构的搭建过程和精髓记录下来,帮助更多有兴趣研发spring cloud框架的朋友,大家来一起探讨spring cloud架构的搭建过程及如何运用于企业项目。

优秀的个人博客,低调大师

(十)Java springcloud B2B2C o2o多用户商城 springcloud架构-SSO单点登录之OAuth2.0登录认证(...

之前写了很多关于spring cloud的文章,今天我们对OAuth2.0的整合方式做一下笔记,首先我从网上找了一些关于OAuth2.0的一些基础知识点,帮助大家回顾一下知识点:一、oauth中的角色client:调用资源服务器API的应用 Oauth 2.0 Provider:包括Authorization Server和Resource Server (1)Authorization Server:认证服务器,进行认证和授权 (2)Resource Server:资源服务器,保护受保护的资源user:资源的拥有者 二、下面详细介绍一下Oauth 2.0 ProviderAuthorization Server:(1)AuthorizationEndpoint:进行授权的服务,Default URL:/oauth/authorize (2)TokenEndpoint:获取token的服务,Default URL:/oauth/token Resource Server:OAuth2AuthenticationProcessingFilter:给带有访问令牌的请求加载认证 三、下面再来详细介绍一下Authorization Server:一般情况下,创建两个配置类,一个继承AuthorizationServerConfigurerAdapter,一个继承WebSecurityConfigurerAdapter,再去复写里面的方法。 主要出现的两种注解:1、@EnableAuthorizationServer:声明一个认证服务器,当用此注解后,应用启动后将自动生成几个Endpoint:(注:其实实现一个认证服务器就是这么简单,加一个注解就搞定,当然真正用到生产环境还是要进行一些配置和复写工作的。) /oauth/authorize:验证 /oauth/token:获取token /oauth/confirm_access:用户授权 /oauth/error:认证失败 /oauth/check_token:资源服务器用来校验token /oauth/token_key:如果jwt模式则可以用此来从认证服务器获取公钥 以上这些endpoint都在源码里的endpoint包里面。 2、@Beans:需要实现AuthorizationServerConfigurer AuthorizationServerConfigurer包含三种配置: ClientDetailsServiceConfigurer:client客户端的信息配置,client信息包括:clientId、secret、scope、authorizedGrantTypes、authorities (1)scope:表示权限范围,可选项,用户授权页面时进行选择 (2)authorizedGrantTypes:有四种授权方式 Authorization Code:用验证获取code,再用code去获取token(用的最多的方式,也是最安全的方式)Implicit: 隐式授权模式Client Credentials (用來取得 App Access Token)Resource Owner Password Credentials(3)authorities:授予client的权限 这里的具体实现有多种,in-memory、JdbcClientDetailsService、jwt等。 AuthorizationServerSecurityConfigurer:声明安全约束,哪些允许访问,哪些不允许访问 AuthorizationServerEndpointsConfigurer:声明授权和token的端点以及token的服务的一些配置信息,比如采用什么存储方式、token的有效期等 client的信息的读取:在ClientDetailsServiceConfigurer类里面进行配置,可以有in-memory、jdbc等多种读取方式。 jdbc需要调用JdbcClientDetailsService类,此类需要传入相应的DataSource. 下面再介绍一下如何管理token:AuthorizationServerTokenServices接口:声明必要的关于token的操作 (1)当token创建后,保存起来,以便之后的接受访问令牌的资源可以引用它。 (2)访问令牌用来加载认证 接口的实现也有多种,DefaultTokenServices是其默认实现,他使用了默认的InMemoryTokenStore,不会持久化token; token存储方式共有三种分别是:(1)InMemoryTokenStore:存放内存中,不会持久化 (2)JdbcTokenStore:存放数据库中 (3)Jwt: json web token 授权类型:可以通过AuthorizationServerEndpointsConfigurer来进行配置,默认情况下,支持除了密码外的所有授权类型。相关授权类型的一些类: (1)authenticationManager:直接注入一个AuthenticationManager,自动开启密码授权类型 (2)userDetailsService:如果注入UserDetailsService,那么将会启动刷新token授权类型,会判断用户是否还是存活的 (3)authorizationCodeServices:AuthorizationCodeServices的实例,auth code 授权类型的服务 (4)implicitGrantService:imlpicit grant (5)tokenGranter: endpoint的URL的配置:(1)AuthorizationServerEndpointsConfigurer的pathMapping()方法,有两个参数,第一个是默认的URL路径,第二个是自定义的路径 (2)WebSecurityConfigurer的实例,可以配置哪些路径不需要保护,哪些需要保护。默认全都保护。 自定义UI:(1)有时候,我们可能需要自定义的登录页面和认证页面。登陆页面的话,只需要创建一个login为前缀名的网页即可,在代码里,设置为允许访问,这样,系统会自动执行你的登陆页。此登陆页的action要注意一下,必须是跳转到认证的地址。 (2)另外一个是授权页,让你勾选选项的页面。此页面可以参考源码里的实现,自己生成一个controller的类,再创建一个对应的web页面即可实现自定义的功能。 下面梳理一下授权获取token流程:(1)端口号换成你自己的认证服务器的端口号,client_id也换成你自己的,response_type类型为code。 localhost:8080/uaa/oauth/authorize?client_id=client&response_type=code&redirect_uri=http://www.baidu.com(2)这时候你将获得一个code值:http://www.baidu.com/?code=G0C20Z (3)使用此code值来获取最终的token: curl -X POST -H "Cant-Type: application/x-www-form-urlencoded" -d 'grant_type=authorization_code&code=G0C20Z&redirect_uri=http://www.baidu.com' "http://client:secret@localhost:8080/uaa/oauth/token" 返回值: {"access_token":"b251b453-cc08-4520-9dd0-9aedf58e6ca3","token_type":"bearer","expires_in":2591324,"scope":"app"} (4)用此token值来调用资源服务器内容(如果资源服务器和认证服务器在同一个应用中,那么资源服务器会自己解析token值,如果不在,那么你要自己去做处理) curl -H "Authorization: Bearer b251b453-cc08-4520-9dd0-9aedf58e6ca3" "localhost:8081/service2(此处换上你自己的url)" 四、Resource Server:保护资源,需要令牌才能访问在配置类上加上注解@EnableResourceServer即启动。使用ResourceServerConfigurer进行配置: (1)tokenServices:ResourceServerTokenServices的实例,声明了token的服务 (2)resourceId:资源Id,由auth Server验证。 (3)其它一些扩展点,比如可以从请求中提取token的tokenExtractor (4)一些自定义的资源保护配置,通过HttpSecurity来设置 使用token的方式也有两种: (1)Bearer Token(https传输方式保证传输过程的安全):主流 (2)Mac(http+sign) 如何访问资源服务器中的API? 如果资源服务器和授权服务器在同一个应用程序中,并且您使用DefaultTokenServices,那么您不必太考虑这一点,因为它实现所有必要的接口,因此它是自动一致的。如果您的资源服务器是一个单独的应用程序,那么您必须确保您匹配授权服务器的功能,并提供知道如何正确解码令牌的ResourceServerTokenServices。与授权服务器一样,您可以经常使用DefaultTokenServices,并且选项大多通过TokenStore(后端存储或本地编码)表示。 (1)在校验request中的token时,使用RemoteTokenServices去调用AuthServer中的/auth/check_token。 (2)共享数据库,使用Jdbc存储和校验token,避免再去访问AuthServer。 (3)使用JWT签名的方式,资源服务器自己直接进行校验,不借助任何中间媒介。 五、oauth client在客户端获取到token之后,想去调用下游服务API时,为了能将token进行传递,可以使用RestTemplate.然后使用restTemplate进行调用Api。 注: scopes和authorities的区别: scopes是client权限,至少授予一个scope的权限,否则报错。 authorities是用户权限。 以上是我从网上找到的一篇写的不错的博客,希望可以帮助大家快速了解OAuth2.0,下一篇文章我们正式介绍OAuth2.0在当前框架中的使用。 从现在开始,我这边会将近期研发的spring cloud微服务云架构的搭建过程和精髓记录下来,帮助更多有兴趣研发spring cloud框架的朋友,大家来一起探讨spring cloud架构的搭建过程及如何运用于企业项目。完整项目的源码来源

资源下载

更多资源
优质分享App

优质分享App

近一个月的开发和优化,本站点的第一个app全新上线。该app采用极致压缩,本体才4.36MB。系统里面做了大量数据访问、缓存优化。方便用户在手机上查看文章。后续会推出HarmonyOS的适配版本。

Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

用户登录
用户注册