本文目录导读:
《SpringCloud微服务架构开发全解析》
SpringCloud微服务架构概述
微服务架构是一种将单一应用程序开发为一组小型服务的方法,每个服务都在自己的进程中运行,并使用轻量级机制(如HTTP RESTful API)进行通信,SpringCloud是一系列框架的集合,它为开发人员提供了构建分布式系统中常见模式的工具,例如配置管理、服务发现、断路器等。
(一)微服务的特点与优势
1、独立部署
图片来源于网络,如有侵权联系删除
- 每个微服务都可以独立地进行开发、测试和部署,这意味着开发团队可以更快地迭代和发布新功能,而不会影响到整个系统的其他部分,一个电商系统中的用户服务,如果需要更新用户注册的逻辑,只需要部署用户服务这个微服务,而不需要重新部署整个电商平台。
2、技术多样性
- 不同的微服务可以根据自身的需求选择最适合的技术栈,对于计算密集型的微服务,可以选择Go语言编写以提高性能;而对于注重业务逻辑处理的微服务,可能使用Java和Spring框架更为合适,这种技术多样性能够充分发挥各种技术的优势,提高系统的整体效率。
3、可扩展性
- 随着业务的增长,可以轻松地对特定的微服务进行水平扩展,如果某个微服务面临高流量的压力,例如订单服务在促销活动期间订单量暴增,可以通过增加订单服务的实例数量来处理更多的请求,而不会影响到其他微服务的正常运行。
(二)SpringCloud核心组件
1、Eureka - 服务发现与注册
- Eureka是SpringCloud中的服务发现组件,在微服务架构中,服务实例的动态变化(如启动、停止或IP地址变更)是常见的情况,Eureka Server作为服务注册中心,各个微服务(Eureka Client)在启动时会向Eureka Server注册自己的信息,包括服务名称、IP地址、端口等,其他微服务可以从Eureka Server查询到所需服务的实例列表,从而实现服务之间的调用,在一个包含商品服务、订单服务和用户服务的电商系统中,订单服务需要调用商品服务获取商品信息,订单服务就可以通过Eureka发现商品服务的实例地址并进行调用。
2、Config - 分布式配置管理
- SpringCloud Config为微服务架构中的配置管理提供了一种集中式的解决方案,它允许将配置文件存储在一个中央仓库(如Git仓库)中,各个微服务可以从Config Server获取自己所需的配置信息,这使得配置的管理更加方便,当需要修改某个配置项时,例如数据库连接字符串,只需要在Config Server中更新,所有相关的微服务就可以获取到新的配置,而不需要逐个修改每个微服务的配置文件。
3、Zuul - API网关
- Zuul是微服务架构中的API网关,它位于客户端和微服务集群之间,Zuul可以对所有的请求进行过滤、路由和监控等操作,它可以对传入的请求进行身份验证,只有合法的用户请求才能被转发到相应的微服务,Zuul可以根据请求的URL将请求路由到不同的微服务实例上,并且可以对请求的流量进行监控,统计每个微服务的调用次数、响应时间等指标。
SpringCloud微服务开发实战
(一)环境搭建
1、开发工具与依赖管理
- 选择合适的开发工具,如IntelliJ IDEA或Eclipse,在项目中,使用Maven或Gradle进行依赖管理,对于SpringCloud项目,需要在项目的构建文件(pom.xml或build.gradle)中添加SpringCloud相关的依赖,要使用Eureka,需要添加spring - cloud - starter - netflix - eureka - server(对于Eureka Server)或spring - cloud - starter - netflix - eureka - client(对于Eureka Client)依赖。
2、创建基础项目结构
- 微服务项目的结构可以按照功能模块进行划分,创建一个父项目,然后在父项目下创建各个微服务的子项目,每个微服务子项目可以有自己的Controller、Service、Repository等层,在Java项目中,典型的项目结构可能如下:
- 父项目:包含公共的依赖管理和一些全局的配置文件。
- 微服务子项目:
- src/main/java:存放Java代码,如com.example.user.service包下的UserService类。
- src/main/resources:存放配置文件,如application.yml或application.properties文件。
图片来源于网络,如有侵权联系删除
(二)服务发现与注册示例 - Eureka
1、创建Eureka Server
- 首先创建一个Spring Boot项目,添加spring - cloud - starter - netflix - eureka - server依赖,在主类上添加@EnableEurekaServer注解来启动Eureka Server,然后在application.yml配置文件中配置Eureka Server的相关属性,如服务端口、注册中心的名称等。
server: port: 8761 eureka: instance: hostname: localhost client: register - with - eureka: false fetch - registry: false service - url: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
- 这里将Eureka Server的端口设置为8761,并且设置它不需要向其他注册中心注册自己(register - with - eureka: false),也不需要从其他注册中心获取服务列表(fetch - registry: false)。
2、创建Eureka Client微服务
- 创建一个普通的Spring Boot微服务项目,添加spring - cloud - starter - netflix - eureka - client依赖,在主类上添加@EnableDiscoveryClient注解,使该微服务成为Eureka Client,在application.yml配置文件中配置该微服务的名称和Eureka Server的地址,
spring: application: name: user - service eureka: client: service - url: defaultZone: http://localhost:8761/eureka/
- 这里将微服务的名称设置为user - service,并指定了Eureka Server的地址为http://localhost:8761/eureka/,当这个微服务启动时,它会向Eureka Server注册自己的信息。
(三)分布式配置管理 - SpringCloud Config
1、创建Config Server
- 创建一个Spring Boot项目,添加spring - cloud - config - server依赖,在主类上添加@EnableConfigServer注解来启动Config Server,然后在application.yml配置文件中配置Config Server从哪里获取配置文件,如果配置文件存储在Git仓库中,可以配置如下:
server: port: 8888 spring: cloud: config: server: git: uri: https://github.com/your - username/your - config - repo.git search - paths: '{application}'
- 这里将Config Server的端口设置为8888,并指定了从名为your - config - repo.git的Git仓库获取配置文件,并且根据应用程序的名称({application})在仓库中搜索对应的配置文件。
2、微服务获取配置
- 在微服务项目中,添加spring - cloud - starter - config依赖,在application.yml或bootstrap.yml(推荐使用bootstrap.yml,因为它在应用程序上下文加载之前就被加载)中配置Config Server的地址,
spring: cloud: config: uri: http://localhost:8888
- 然后就可以在微服务中使用@Value注解或@ConfigurationProperties注解来获取配置文件中的属性值,如果配置文件中有一个名为user.username的属性,可以在Java代码中这样使用:
import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @Component public class UserConfig { @Value("${user.username}") private String username; // 可以在类的其他方法中使用username变量 }
(四)API网关 - Zuul
1、创建Zuul网关项目
- 创建一个Spring Boot项目,添加spring - cloud - starter - netflix - zuul依赖,在主类上添加@EnableZuulProxy注解来启动Zuul网关,在application.yml配置文件中配置Zuul的路由规则等属性。
server: port: 8080 spring: application: name: zuul - gateway zuul: routes: user - service: path: /user - service/** url: http://localhost:8081
- 这里将Zuul网关的端口设置为8080,并且定义了一个名为user - service的路由规则,当请求的路径以/user - service/开头时,Zuul会将请求转发到http://localhost:8081这个地址(假设这是user - service微服务的地址)。
2、Zuul的过滤器功能
- Zuul允许开发人员编写自定义的过滤器来对请求进行处理,可以编写一个前置过滤器来对请求进行身份验证,创建一个类实现ZuulFilter接口,重写其中的方法,在shouldFilter方法中决定是否执行该过滤器,在run方法中编写过滤逻辑。
import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.context.RequestContext; import com.netflix.zuul.exception.ZuulException; import javax.servlet.http.HttpServletRequest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class AuthenticationFilter extends ZuulFilter { private static final Logger logger = LoggerFactory.getLogger(AuthenticationFilter.class); @Override public String filterType() { return "pre"; } @Override public int filterOrder() { return 1; } @Override public boolean shouldFilter() { return true; } @Override public Object run() throws ZuulException { RequestContext ctx = RequestContext.getCurrentContext(); HttpServletRequest request = ctx.getRequest(); String authHeader = request.getHeader("Authorization"); if (authHeader == null) { logger.error("No Authorization header found in request"); ctx.setSendZuulResponse(false); ctx.setResponseStatusCode(401); return null; } // 这里可以进一步验证Authorization头中的令牌等信息 return null; } }
- 在这个例子中,过滤器类型为"pre"(前置过滤器),如果请求的Authorization头为空,则拒绝该请求,返回401状态码。
图片来源于网络,如有侵权联系删除
微服务的监控与治理
(一)Hystrix - 断路器
1、Hystrix的作用
- 在微服务架构中,服务之间的调用可能会因为网络故障、服务过载等原因失败,Hystrix是Netflix开源的一个库,用于处理分布式系统中的延迟和容错,它通过在服务调用方使用断路器模式来防止一个服务的故障扩散到整个系统,当某个服务的调用失败率达到一定阈值时,Hystrix会自动切断对该服务的调用,直接返回一个默认值或者执行一个备用逻辑,从而避免调用方一直等待故障服务的响应,导致资源耗尽。
2、Hystrix在SpringCloud中的使用
- 在SpringCloud项目中,使用spring - cloud - starter - netflix - hystrix依赖来集成Hystrix,在一个调用其他微服务的服务中,可以在方法上使用@HystrixCommand注解来标记该方法受Hystrix保护。
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; @Service public class OrderService { @Autowired private RestTemplate restTemplate; @HystrixCommand(fallbackMethod = "getFallbackProducts") public String getProducts() { return restTemplate.getForObject("http://product - service/products", String.class); } public String getFallbackProducts() { return "No products available currently"; } }
- 在这个例子中,OrderService中的getProducts方法调用了product - service微服务,如果对product - service的调用失败,Hystrix会执行getFallbackProducts方法作为备用逻辑,返回一个默认的消息。
(二)Sleuth - 分布式链路追踪
1、链路追踪的必要性
- 在微服务架构中,一个用户请求可能会经过多个微服务的处理,当出现问题时,很难确定是哪个微服务环节出现了故障,Sleuth是SpringCloud中的分布式链路追踪组件,它可以为每个请求生成一个唯一的跟踪标识(Trace ID),并且在请求经过各个微服务时,记录每个微服务的处理时间、调用关系等信息,这样,当出现问题时,可以通过这个跟踪标识快速定位问题所在的微服务和具体的操作。
2、Sleuth的使用示例
- 在SpringCloud项目中,添加spring - cloud - starter - sleuth依赖,在日志配置中,可以配置日志输出包含Sleuth的跟踪信息,在logback.xml配置文件中,可以添加如下内容:
<configuration> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d{HH:mm:ss.SSS} [%X{X - B3 - TraceId}/%X{X - B3 - SpanId}] [%thread] %- 5level %logger{36} - %msg%n</pattern> </encoder> </appender> <root level="INFO"> <appender - ref ref="CONSOLE"/> </root> </configuration>
- 当一个请求经过多个微服务时,在每个微服务的日志中都会输出包含Trace ID和Span ID的信息,通过这些信息可以构建出请求的完整链路。
微服务的安全
(一)OAuth2 - 授权框架
1、OAuth2原理
- OAuth2是一个开放标准的授权框架,用于在不共享用户密码的情况下,授权第三方应用访问用户资源,它定义了多种授权模式,如授权码模式、密码模式、客户端凭证模式等,在微服务架构中,OAuth2可以用于保护微服务之间的通信以及用户对微服务的访问,在一个包含多个微服务的企业应用中,用户通过身份验证后,会获得一个访问令牌(Access Token),这个令牌可以用于访问受保护的微服务资源。
2、在SpringCloud中实现OAuth2
- 在SpringCloud项目中,可以使用spring - cloud - starter - oauth2依赖来实现OAuth2,需要创建一个授权服务器(Authorization Server),在授权服务器中配置客户端信息(如客户端ID、客户端密钥、授权类型等)、用户信息(可以从数据库或其他数据源获取)以及令牌的颁发和验证逻辑。
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer; @Configuration @EnableAuthorizationServer public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { @Autowired private AuthenticationManager authenticationManager; @Autowired private PasswordEncoder passwordEncoder; @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.inMemory() .withClient("client - id") .secret(passwordEncoder.encode("client - secret")) .authorizedGrantTypes("authorization_code", "password", "client_credentials") .scopes("read", "write") .accessTokenValiditySeconds(3600); } @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { endpoints.authenticationManager(authenticationManager); } @Override public void configure(AuthorizationServerSecurityConfigurer security) throws Exception { security.tokenKeyAccess("permitAll()") .checkTokenAccess("isAuthenticated()"); } }
- 在这个例子中,在内存中配置了一个客户端,定义了客户端的ID、密钥、授权类型、权限范围和令牌有效期等信息,配置了授权服务器的端点(endpoints)和安全(security)相关的属性。
- 在微服务中作为资源服务器(Resource Server),可以使用@EnableResourceServer注解来保护微服务资源,并且可以通过配置来验证传入的访问令牌,
import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpServletRequestMatcherRegistry; import org.springframework.security.config.annotation.web.configuration.EnableResourceServer; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer; @Configuration @EnableResourceServer public class ResourceServerConfig extends ResourceServerConfigurerAdapter { @Override public void configure(ResourceServerSecurityConfigurer resources) throws Exception { resources.resourceId("resource - id"); } @Override public void
标签: #springcloud #微服务架构 #开发实战
评论列表