目前为止绝大部分的web应用软件采用单体应用,全部的应用的用户UI、业务逻辑、数据库访问都打包在一个应用程序上。html
缺点:java
开发相互干扰,随着应用的不断升级沟通协调成本增长 应用上线因为某个功能升级致使须要总体的构建、总体测试、总体发布
把单体应用拆分红小的、松藕合分布式服务的形式 每一个应用必定是独立构建、独立部署与测试,应用也是独立发布,应用于应用直接一般经过restful API接口的形式进行相互调用。 解决了单体应用带来的困扰。 web
2002,Rod Johonson发表了<<Expert One-on-One J2EE Design and Development>>, 包含了3万行的代码在包com.interface21中 2003,Juerge Hoeller,Yann Caroff 联系Rod,将书中代码开源,Yann提出Spring这个词,冠于书中代码; 并发布0.9,使用Apache 2.0协议;Thomas Risberg负责Spring JDBC;Ben Alex将Acegi Security贡献给Rod和Juergen 2004,1.0发布 2005,<<Professional Java Development with Spring Framework>> <<Pro Spring>>出版;1.2.6发布。 AspectJ Leader Adrian Coyler加入Interface21做为首席科学家; 2006,Security 1.0、Spring webflow 1.0发布;Spring 2.0发布; 2007,Spring Batch、WebService、Integration发布;Spring 2.5发布; 2008,Spring Integration 1.0,Spring 2.5.6,Spring Batch 1.0;买了g2One,一家提供Groovy and Grails的公司; 2009,被VMWare发了42亿美金买下;Spring Python、STS发布、3.0发布(将包拆开,不提供超级包),买了Cloud Foundry; 2010,VMWare买了RabbitMQ公司,得到RabbitMQ和Redis技术; 2011,Spring 3.一、Spring AMQP、Spring Data JPA、Spring-data-common 1.0 、Spring Data Redis、Spring Data Mongodb发布; 2012,Rod Johnson离开VMWare;Spring Android、Mobile发布; 2013,VMWare 和 EMC 协力组建了一家公司,Pivotal。Spring 4.0、Spring Boot发布; 2014,Spring 4.1.三、SpringBoot 1.0发布; 2015,Spring 4.二、4.3发布; 2016,Spring 4.3 GA 2017,Spirng 5.x
Spring的出现让EJB等重量级的容器技术逐渐走向末路。 Spring 经过对Bean的生命周期的管理,能够快速方便的实现业务的逻辑处理。 Spring 能够方便的整合几乎全部的主流的开源项目如JPA,缓存,消息组合等等,方便的进行开发。spring
本实战目的: 全程演示如何建立一个基础的、可用的Spring cloud分布式应用系统 演示Spring Cloud各部分组件如何在应用以前协调、调用。 了解整个Spring Cloud的项目基本状况,有一个初步的认识。 本实战JAVA采用JDK8 Spring Boot版本采用最新2.1.0 release. Spring Cloud版本采用Greenwich.M1。数据库
阿里云的spring cloud 架构图在线设计地址: https://www.freedgo.com 便可使用Freedgo Desing 进行图形设计.api
架构预览地址:缓存
<a target='blank' href='https://www.freedgo.com/draw_index.html?#Uhttps://www.freedgo.com/templates/network/springcloud_aliyun.xml'>https://www.freedgo.com/draw_index.html?#Uhttps://www.freedgo.com/templates/network/springcloud_aliyun.xml</a>安全
Freedgo Design 是一in款在线绘制专业图形的网站。Freedgo Design能够绘制各类类型的图形,针对业务逻辑的流程图,软件设计ER模板,工做流,各类云平台的系统部署架构图包括阿里云、AWS云、腾讯云、Oracle、Asure云、IBM云平台等。服务器
开发工具:Intellij idea 一、 创建一个mvn 工程项目 使用的java jdk 采用jdk8restful
创建子模块discovery-service
咱们能够看到mvn 依赖导入了netflix-eureka-server Spring boot 会启动服务发现服务
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency>
创建子模块config-service
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-server</artifactId> </dependency>
服务路由采用 Netflix Zuul 经过服务路由做为eureka client,能够被发现服务监控
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-zuul</artifactId> </dependency>
基础的组件建立完毕
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-oauth2</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-security</artifactId> </dependency>
传统服务发现方式经过网络DNS和负载均衡设备实现,须要网络和硬件设置支持,维护成本高,网络环境复杂 居于云的服务发现具备以下优势 高可用,热部署 负载均衡 健康检查,容错机制 抽象服务的逻辑名称 使用Spring与Netflix Eureka实现服务发现
实现服务发现功能须要配置服务发现端及须要注册服务配置客户端 一、 发现服务端配置 服务注册须要30 s 的时间才能显示在 Eureka 服务中,由于 Eureka 须要从服务接收3次连续心跳包 ping,每次心跳包 ping 间隔10 s,而后才能使用这个服务。在部署和测试服务时,要牢记这一点。 application.yml
server: port: 8761 # Eureka 服务器将要监听的端口 eureka: client: registerWithEureka: false #不要使用 Eureka 服务进行注册 fetchRegistry: false #不要在本地缓存注册表信息
使用一个新的注解@EnableEurekaServer,就可让咱们的服务成为一个 Eureka 服务
二、 服务发现客户端配置 以config-service为例 须要作2件事情 一、 成为服务发现的客户端
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>
二、 配置application.yml(对应config-server来讲咱们只须要配置以下)
spring: cloud: config: discovery: enabled: true
启动运行查看
http://localhost:8761/eureka/apps/config-service。 应用做为服务发现的客户端设置 一、 添加客户端依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>
二、 配置application.yml
spring: application: name: business_service eureka: instance: preferIpAddress: true #注册服务的 IP,而不是服务器名称 client: registerWithEureka: true #向 Eureka 注册服务 fetchRegistry: true serviceUrl: #拉取注册表的本地副本 defaultZone: http://localhost:8761/eureka/ #Eureka 服务的位置
一样经过mvn spring-boot:run 打开http://localhost:8761 ,business_service已经注册成功
使用服务发现查找服务
OAuth2协议说明:
总体OAuth协议包括两方面: 一、 访问受权:用户必须经过受权获取令牌 二、 资源权限:经过受权的用户访问受保护的资源,根据定义访问权限来决定是否能够访问资源 配置说明: 启用OAuth受权服务 增长@EnableAuthorizationServer 用于告诉 Spring Cloud,该服务将做为 OAuth2 服务
package com.yuaoq.train.business; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; @SpringBootApplication @EnableResourceServer @EnableAuthorizationServer public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }
OAuth访问受权配置,配置注册的客户端应用程序
@Configuration public class Auth2Config extends AuthorizationServerConfigurerAdapter { @Autowired private AuthenticationManager authenticationManager; @Autowired private UserDetailsService userDetailsService; // 覆盖 configure()方法。这定义了哪些客户端将注册到服务 @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.inMemory() .withClient("yuaoq") .secret("{noop}secret") .authorizedGrantTypes( "refresh_token", "password", "client_credentials") .scopes("webclient","mobileclient"); } // 该方法定义了 AuthenticationServerConfigurer 中使用的不一样组件。这段代码告诉 Spring 使用 Spring 提供的默认验证管理器和用户详细信息服务 @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { endpoints .authenticationManager(authenticationManager) .userDetailsService(userDetailsService); } }
配置用户权限
@Configuration public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter { @Override @Bean // AuthenticationManagerBean 被 Spring Security 用来处理验证 public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } // Security 使用 UserDetailsService 处理返回的用户信息,这些用户信息将由 Spring Security 返回 @Override @Bean public UserDetailsService userDetailsServiceBean() throws Exception { return super.userDetailsServiceBean(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { // configure()方法是定义用户、密码和角色的地方 auth.inMemoryAuthentication() .withUser("admin") .password("{noop}password") .roles("ADMIN","USER") .and() .withUser("anyone") .password("{noop}password") .roles("USER"); } }
获取用户信息(提供给其余服务获取用户信息使用)
@GetMapping(value = "/auth/user") public Map<String, Object> user(OAuth2Authentication user) { Map<String, Object> userInfo = new HashMap<>(); userInfo.put("user", user.getUserAuthentication().getPrincipal()); userInfo.put("authorities", AuthorityUtils.authorityListToSet(user.getUserAuthentication().getAuthorities())); return userInfo; }
经过postman测试 自此提供了一个用户认证的微服务模块.
一、 对外提供restful Api @RestController:由spring web提供的居于restful 的接口标签 生成一个restful api
@PostMapping("/list") public ResponseEntity<List<String>> getBusiness() throws Exception { List<String> list = new ArrayList<String>(); list.add("a"); list.add("b"); return Optional.of(list) .map(a -> new ResponseEntity<List<String>>(a, HttpStatus.OK)) .orElseThrow(() -> new Exception("error")); }
使用postman调用接口
从postman返回的结果能够看到401,未受权。 由于business_service服务引入了spring-cloud-starter-security 那么默认是会对全部访问作安全控制。
二、 服务的受权保护 如今business/list 是未受权,那怎么配置一个受保护的oauth2.0资源,经过以下步骤 设置服务是一个受oauth保护的资源 定义应用的OAuth属性定义回调 URL
security: oauth2: resource: user-info-uri: http://localhost:8282/auth/user
定义受权用户能够访问
@Configuration public class ResourceServerConfig extends ResourceServerConfigurerAdapter { // antMatchers()容许开发人员限制对受保护的 URL 和 HTTP DELETE 动词的调用 // hasRole()方法是一个容许访问的角色列表,该列表由逗号分隔 @Override public void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers(HttpMethod.POST, "/api/v1/business/**") .hasRole("ADMIN") .anyRequest() .authenticated(); } }
该段代码说明具备ADMIN角色的用户能够访问/api/v1/business/ 下的全部的POST 请求 验证以下:
至此经过OAuth2.0保护微服务的基本作法已经完成。
2.2.4. 服务路由网关 服务网关:服务客户端再也不直接调用服务。取而代之的是,服务网关做为单个策略执行点(Policy Enforcement Point,PEP),全部调用都经过服务网关进行路由,而后被路由到最终目的地。 @EnabeZuulServer使用此注解将建立一个 Zuul 服务器,它不会加载任何 Zuul 反向代理过滤器,也不会使用 Netflix Eureka 进行服务发现.
成为一个服务网关步骤: 一、 添加@EnableZuulProxy 二、 在application.yml添加route 规则
zuul: sensitive-headers: set-cookies routes: business_service: /busi/**
经过postman测试以下: