《深刻实践Spring Boot》阅读笔记之二:分布式应用开发

 

上篇文章总结了《深刻实践Spring Boot》的第一部分,这篇文章介绍第二部分:分布式应用开发,以及怎么构建一个高性能的服务平台。html

主要从如下几个方面总结:前端

  • Spring Boot SSO
  • 使用分布式文件系统
  • 云应用开发
  • 构建高性能的服务平台

Spring Boot SSO

上篇文章提到了安全设计,使用Spring Security进行用户验证和权限验证,但一个企业级的应用系统可能存在不少应用系统,每一个应用系统都须要设计安全管理,但不可能为每个应用系统都设计一套安全管理,这样不但耗时耗力,并且要作重复的工做,也不适宜创建统一的用户中心。vue

可使用单点登陆SSO的方式创建一个登陆认证系统,而且实现对用户的统一管理。本章在使用Spring Security安全管理的基础上,再结合OAuth2认证受权协议来实现的,它不但适用于大型的分布式管理系统,也适用于为第三方提供统一的用户管理和认证的平台。java

做者给出了一个完整的实例,以模块化的设计方式进行实现,整个demo的代码能够在github上查看。(https://github.com/chenfromsz/spring-boot-ssomysql

demo说明

我在本地运行了demo,经过chrome查看了系统间跳转的过程,先说明下模块的划分,而后看下运行效果。git

项目 工程 类型 功能
数据库管理模块 mysql 程序集成 数据库管理
安全配置模块 security 程序集成 安全策略配置和权限管理
登陆认证模块 login Web应用 SSO登陆认证(80)
共享资源模块 resource Web应用 共享资源(8083)
客户端应用1 web1 Web应用 客户端1(8081)
客户端应用2 web2 Web应用 客户端2(8082)

访问首页时,跳转到登陆页面,输入正确的帐号、密码、验证码。
登陆成功后,跳转到首页:
首页github

访问web1系统、web2系统时不须要从新登陆,会自动登陆:
web1系统首页web

「登陆认证模块」主要包括验证用户帐号、集成OAuth2服务端端功能。spring

「安全配置模块」是一个公共模块,集成了SSO客户端的安全策略配置和权限管理功能,供客户端引用。sql

「数据库管理模块」是一个公共模块,主要提供数据库的访问功能,供其余模块使用。

「共享资源模块」提供了一个简单的公共服务,2个客户端应用可经过spring-cloud-zuul直接调用。

后面会重点介绍下登陆认证模块,其余模块比较简单,再也不过多介绍。

模块化设计能够提升代码的复用性,避免重复开发,实例中的「数据库管理模块」和「安全配置模块」能够被其余模块共用,减小大部分重复工做。
做者的这种设计方式值得咱们学习,在之后的系统设计中,应多借鉴这种方式。

登陆认证模块

我画了一个流程图,先了解下用户认证、权限验证的基本过程:
基本处理流程

整个处理流程,Spring Security都帮咱们自动实现了,咱们只须要对帐号中心数据源、权限中心数据源进行配置和扩展,另外,能够对登陆页面进行扩展,配置权限管理规则、防攻击策略、记住登陆状态。

为了实现多个系统只需登陆一次,须要集成OAuth2。添加spring-cloud-starter-oauth2依赖,编写一个配置类,继承AuthorizationServerConfigurerAdapter,并声明下@EnableAuthrizationServer来启用OAuth2的认证服务器功能。

OAuth2有不少受权机制,本例中使用authorization_code机制,具体配置就不过多说明了,能够参考下面的几篇文章:

[1] 初步理解Spring Security并实践
[2] security OAuth2.0 提供者实现原理
[3] jwt token介绍
[4] security OAuth2.0 jwt完美整合例子

使用分布式文件系统

有这样一个问题,若是上传文件,如上传图片,应该怎样保存,保存在哪里?

传统的作法通常都保存在Web服务器所在机器中。但随着业务的日益发展,可能上传的文件会累积愈来愈多,单台机器每每会不堪重负,再加上一些负载均衡的配置和服务,须要分布式文件系统解决。

在诸多分布式的文件系统中,FastDFS是比较优秀的分布式文件系统。FastDFS是一个彻底开源的分布式文件系统,使用比较简单方便,并且性能也很优秀,存储容量和访问性能可按需求进行线性横向扩展。

FastDFS服务端和客户端的安排、配置、管理都比较简单,书中描述的也比较详细,就不在此赘述了。

云应用开发

Spring Cloud 是一套云应用开发工具集,为分布式的微服务开发提供了一整套简单易用的使用工具。Spring Cloud主要包括配置管理、服务发现、动态路由、负载均衡、断路器、安全管理、事件总线、分布式消息等组件的开发工具包。

Spring Cloud与Spring Boot 关系密切,可以臻于完美的几何使用。

本章重点介绍了配置服务、发现服务、动态路由和断路器、监控服务。

配置服务

一个项目工程老是须要一些配置,好比,要配置服务器的端口、访问数据库的参数等。一个大型的分布式系统可能存在不少这样须要配置的项目工程,配置管理是一个庞大的工程,须要一个单独的系统专门管理各个项目的配置。

经过Spring Cloud的配置管理,只需建立一个简单的工程,就能够实现分布式配置管理服务,同时还支持在线更新。

第一步,配置管理服务器
引入spring-cloud-config-server依赖,建立一个主程序:

@SpringBootApplication
@EnableConfigServer
@EnableDiscoveryClient
public class ConfigApplication{
    public static void main(String[] args) {
        SpringApplication.run(ConfigApplication.class, args);
    }
}

配置文件的存储目前支持使用本地存储、Git以及Subversion等方式。以Git方式为例,说明本地配置文件:

spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/chenfromsz/spring-cloud-config-repo
  rabbitmq:
      addresses: ${vcap.services.${PREFIX:}rabbitmq.credentials.uri:amqp://${RABBITMQ_HOST:192.168.1.215}:${RABBITMQ_PORT:5672}}
      username: alan
      password: alan

服务端会自动从指定的git地址获取配置信息。raabitmq的配置用于通知客户端应用配置更新。

第二步,配置管理的客户端
须要在工程中引入spring-cloud-starter-config依赖,使用配置管理服务以后,若是本地的配置文件与配置管理服务器的配置文件有相同的配置项,将优先使用配置管理服务器的配置项。

客户端的配置文件bookstrap.yml以下:

spring:
  application:
    name: data
  profiles:
    active: development
  cloud:
    config:
      uri: http://localhost:8888
  rabbitmq:
        addresses: amqp://192.168.1.214:5672
        username: alan
        password: alan

其中,name用来指定应用的名称和配置文件的名称,uri设定配置服务服务端的地址和端口,profiles为使用配置文件名称的后缀部分,用于绑定不一样的线上环境。

第三步,使用配置
若是配置文件中有cloud.config.test配置项,能够这样使用

@Value("${cloud.config.test:World!}") String msg;

另外,可使用spring-cloud-bus-amqp依赖,经过事件总线的方式,实如今线更新全部客户端的配置。

发现服务

在分布式系统中,可能存在不少应用和服务,各个服务渎职自主地管理自身的数据。服务与服务之间,须要互相共享一些数据,传统的方式须要本身编写一些接口程序,还须要使用复杂的配置来实现,使用Spring Cloud能够轻易作到这些。

第一步,建立发现服务器
引入spring-cloud-starter-eureka-server依赖,建立一个简单的主程序便可:

@SpringBootApplication
@EnableEurekaServer
public class DiscoveryApplication {
    public static void main(String[] args) {
        SpringApplication.run(DiscoveryApplication.class, args);
    }
}

第二步,建立客户端
引入spring-cloud-starter-eurake依赖,主程序中加入@EnableDiscoveryClient启用发现服务的客户端。

配置文件以下:

eureka:
  instance:
    hostname: discovery
  client:
    registerWithEureka: false
    fetchRegistry: false
    serviceUrl:
      defaultZone: http://192.168.1.221:${server.port}/eureka/
动态路由和断路器

如何在服务间相互调用呢,可使用动态路由、断路器和故障容错等功能。

引入spring-cloud-starter-zuul、spring-cloud-starter-hystrix依赖,添加@EnableZuulProxy和@EnableHystrix注解便可。

为了便于测试,能够经过共享Rest资源将repository的类直接暴露出来,很神奇吧,以下:

@RepositoryRestResource(collectionResourceRel="users",path="users")
public interface UserRepository extends GraphRepository<User> {
    User findByName(@Param("name") String name);

    @Query("MATCH (u:User) WHERE u.name =~ ('(?i).*'+{name}+'.*') RETURN u")
    Collection<User> findByNameContaining(@Param("name") String name);

}

能够经过http://localhost/usershttp://localhost/users/123 之类的方式访问。

经过如下3种方式调用其余服务对外暴露的接口:

  • JavaScript:前端直接调用
  • RestTemplate:后端调用
  • FeignClient:特殊方式

以RestTemplate为例说明一个服务调用data服务的例子:

@Autowired @LoadBalanced
 RestTemplate restTemplate;
 @HystrixCommand(fallbackMethod = "getUserFallback")
     public User getUserByName(String name) {
         Map<String, Object> params = new HashMap<>();
         params.put("name", name);
         User user = restTemplate.getForObject("http://data/user/findByName?name={name}", User.class, params);

         return user;
 }

上面例子中使用了@HystrixCommand用于实现断路器,当一个系统服务忽然出现故障时,会自动阻断对服务的访问和调用,转而调用备用方法。

监控服务

分布式服务系统中运行着不少服务,必须有一个管理机制和方法,可以一目了然地随时了解各个服务的运行状况及其健康指数。

使用Spring Cloud的监控服务,能够实时监控应用的运行状况。使用很简单,引入spring-cloud-starter-hystrix-dashboard依赖,建立一个主程序便可:

@SpringBootApplication
@Controller
@EnableHystrixDashboard
public class HystrixApplication{
    @RequestMapping("/")
    public String home() {
        return "forward:/hystrix";
    }

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

具体监控指标可参看官网文档。

构建高性能的服务平台

使用Spring Cloud开发的微服务,其独立而又相对隔离的特性,与Docker的理念有殊途同归之妙,因此使用Docker发布微服务,可以发挥其最大的优点,而且能够很是轻易地构建一个高性能和高可用的服务平台。

Docker能够很方便地建立和管理镜像,以及管理已经生成的和正在运行的容器。镜像是一种文件存储方式,能够把许多文件作成一个镜像文件。容器是镜像运行的一个实例,运行一个镜像,就会生成一个容器,容器生成以后,就能够在容器中管理应用系统了。

Docker的安装和发布服务,网上的资料不少,这里就不赘述了。

另外,可使用其余一些服务管理工具来构建高性能和高可用的服务平台。docker-compose工具是Docker容器管理工具集,能够很方便地用来建立和重建容器、执行启动和中止容器等管理操做,以及查看整个服务体系的运行状况和输出日志等。使用docker-compose工具,只要一条指令就能启动整个分布式服务体系。

经过本篇文章的介绍,你们能够感觉到Spring Cloud在构建分布式应用时提供的便捷性,减小了大量的工做量。同时为咱们考虑了方方面面,加强了系统的稳定性、高性能。
做者把全部代码都上传到github,你们能够直接运行demo深刻了解。
[1] Spring Boot SSO:https://github.com/chenfromsz/spring-boot-sso
[2] 云应用开发:https://github.com/chenfromsz/spring-boot-cloud

 


情情说

 

相关文章
相关标签/搜索