200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > SpringCloud入门总结 + 使用SpringCloud搭建微服务项目

SpringCloud入门总结 + 使用SpringCloud搭建微服务项目

时间:2024-06-06 22:08:21

相关推荐

SpringCloud入门总结 + 使用SpringCloud搭建微服务项目

SpringCloud

1.认识微服务2.认识spring Cloud3.Spring Cloud Eureka 服务发现框架3.1认识Eureka3.2 实战--开发并部署Eureka Server 4 SpringCloud Ribbon 负载均衡4.1 什么是负载均衡4.2 认识Ribbon4.3 Ribbon与Nginx4.4 Ribbon常见的均衡算法4.5 实战 5 SpringCloud Hystrix 容错保护5.1 认识Hystrix5.2 熔断和降级5.3 实战 6 SpringCLoud Zull 服务网关6.1 认识zull6.2 实战zull的路由功能zull的过滤功能 7 总结

1.认识微服务

什么是微服务

将一个独立的系统拆分成若干个小的服务,每个小的服务独立运行,服务与服务之间采用http轻量协议(比如Restful)进行通信。每个服务所拥有的功能具有独立性强、高内聚的特点,这样的设计就实现了单个服务的高内聚,服务与服务之间的低耦合效果,这一个一个的小服务就是微服务,基于这种方法设计的系统架构即微服务架构。优点

1、微服务架构采用去中心化思想,服务之间采用RESTful等轻量协议通信,服务拆分粒度细,服务之间松耦合,开发效率高。

2、可以更准确地指定每个服务的优化方案,充分利用资源,避免资源浪费,比如一个商城系统中,订单服务访问量大可以多部署几台,用户登录服务调用少可以少部署几台。

3、产品迭代周期更短,适用于现在的互联网时代。缺点

1、随着系统的增大,服务数量变多,服务治理成本高。

2、分布式系统开发需要的技术成本高。微服务技术栈

1、服务治理:服务的注册与发现。

2、容错:容错机制避免服务雪崩。

3、监控跟踪:监控资源利用、服务响应、容器资源利用情况。

4、消息总线:消息队列、异步通信。

5、配置管理:统一配置管理。

6、负载均衡,网关路由:高可用、集群部署,校验、请求转发、服务集成。

2.认识spring Cloud

什么是springCloud

SpringCloud是spring为开发人员提供的一个一站式的微服务架构解决方案,是若干个框架的集合,包括spring-cloud-eureka、spring-cloud-config等20个左右的子项目。我们平常搭建微服务项目中需要用到服务注册与发现负载均衡网关路由容错保护配置中心消息总线数据监控等,这些SpringCloud都为我们提供了相应的解决方案,使我们能在SpringBoot项目的基础上轻松地搭建一个微服务项目。SpringCloud技术栈

除了springCloud的这些之外,还有很多公司提供一些优秀的技术用于解决微服务中的问题:

服务治理:Dubbo(阿里巴巴)、Dubbox(当当)等

配置管理:Disconf(百度)、QConf(360)、Diamood(淘宝)等

服务跟踪:Hydra(京东)、Zipkin(Twitter)等为什么使用SpringCloud

微服务的兴起提高了生产力,但同时也带来了一定的技术成本,比如上面说的一些公司也有自己的对应的解决某个模块的方案,但不够全面,Spring整合封装了一些能解决微服务搭建过程中不同模块需要用到的技术(其中很多技术来源于Netfix)。使用SpringCloud可以一站到底,省去了我们去整合各家技术的成本,简单快捷。

3.Spring Cloud Eureka 服务发现框架

3.1认识Eureka

微服务项目随着业务的增多,系统的不断扩大,微服务数量也逐渐增多,不利维护,服务治理是让服务自维护,解放开发者。Spring Cloud Eureka 是对Netflix公司的Eureka的二次封装,它实现了服务治理的功能。有服务端:服务的注册中心,客户端:服务的注册与发现。

服务发现框架,整个过程有三个角色:服务提供者,服务消费者,服务治理中心。

服务提供者EurekaClient:提供服务,并向注册中心注册,供消费者使用。即服务注册,它提供自身的元数据,比如IP地址、端口,运行状况等注册到EurekaServer中

服务消费者EurekaClient:需要使用一些服务的用户。有的服务消费者也需要向EurekaServer中注册,因为它也可能被其他消费者调用,这个时候它的角色也是提供者。

服务治理中心EurekaServer:相当于一个中介,搭建在服务提供者与消费者之间的桥梁,服务提供者把自己注册到服务中介那里,服务消费者如果需要服务就去中介那里获取服务列表,以调用已经在服务注册中心注册过的运行正常的服务

获取注册列表信息:Eureka客户端会从服务器获取注册信息并缓存在本地。该列表信息会定期更新一次(30秒)。每次获取缓存的信息可能有客户端在本地缓存的信息不同,Eureka客户端会自动处理。如果由于某种原因导致注册列表信息不能及时匹配,Eureka客户端会重新获取整个列表信息。

服务续约:Eureka客户端默认情况下会每隔30秒发送一次心跳来续约,告诉Eureka Service该我依然存在,没有问题,可以被其他服务正常调用。但是如果服务器90秒还没有收到某个服务的续约,它会将该服务实例从注册列表中删除。

自我保护机制:如果遇到某种因素,比如网络波动,Eureka的自我保护机制就是如果在15分钟内超过85%的客户端没有正常地发送心跳,那么Eureka Server就会认为客户端与治理中心之间出现了故障,从而启动自我保护机制。在Eurreka Server开启自我保护机制时:①不再从注册列表中移除长时间没有发送心跳的服务。②客户端任然能向治理中心注册和查询服务,但是只能当前节点可用,信息不会同步到其他节点,当网络回复或故障排除后在同步到其他节点,恢复正常工作。

通过在配置文件中配eureka.server.enable-self-preservation: true来开启自我保护机制。

服务下线: Eureka客户端需要关闭程序时会向服务器治理中心发送取消请求,发送后,该客户端实例将从服务器的实例注册表信息中删除。

服务剔除:有主动就有被动,客户端可以主动申请删除服务实例,那在默认情况下,服务器连续三个续约周期(90秒)没有收到客户端发来的心跳续约,Eureka服务器就会将该服务实例从服务注册列表中删除。

3.2 实战–开发并部署Eureka Server

**本文示例涉及源码的下载地址**:>>>github  >>> csdn下载

本次微服务搭建的开发环境:Java8、maven 3.6.0、SpringBoot 2.1.14、SpringCloud Greenwich.SR1、MySql 5.7、Idea。

其中SpringBoot与SpringCloud有版本对应关系,版本不对可能会导致依赖找不到(以踩坑)等问题,还有一个坑就是不同的SpringCloud的版本引入Eureka、hystrix等依赖名时的名称也不同。另外SpringCloud的版本号非常特别,使用的是伦敦地铁站的名称命名。

版本号关系表:

1、创建一个SpringBoot项目

2、添加SpringCloud、Eureka相关依赖

<!-- 导入Spring Cloud的依赖管理 --><dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>Greenwich.SR1</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement>

<!-- 导入Eureka服务的依赖 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></dependency>

3.在启动类添加注解@EnableEurekaServer 申明这是一个eureka服务

4.配置application.yml

5.通过启动时动态传入端口号等信息部署两台Eureka Server,并且互相注册,实现高可用。

在idea中配置application.yml中的参数并启动:

6.访问

地址 http://127.0.0.1:6869/ http://127.0.0.1:6868/

4 SpringCloud Ribbon 负载均衡

4.1 什么是负载均衡

负载均衡分为服务器端负载均衡和客户端负载均衡,是微服务中必须使用到的技术,通过负载均衡可以实现系统的高可用。负载均衡可以通过硬件和软件实现,比如,硬件有:F5、Array等,软件有:LVS,Nginx等。

如上图,用户请求先到达负载均衡,然后由负载均衡器根据负载均衡算法将请求转发到各个微服务。比如一个秒杀系统,为了高可用会做一个集群,就像上图一样,三个微服务都是秒杀系统服务,如果没有进行负载均衡,对其中某个服务进行大量请求,就很可能会导致这个系统奔溃,而其他两个系统基本不请求,就会变得鸡肋。所以负载均衡可以为微服务集群分担请求,减小系统压力

常见的几种负载均很算法有:轮训、随机、加权轮训、加权随机、地址哈希等方法。

4.2 认识Ribbon

Ribbon是一个基于客户端的负载均衡工具,它从Eureka server获取服务列表,然后根据负载均衡算法请求到具体的服务。

4.3 Ribbon与Nginx

Ribbon与Nginx一样都可以实现负载均衡。区别在于:

Ribbon

1.基于客户端的,先在客户端进行负载均衡才进行请求,在调用接口时,会在Eureka service 上获取服务列表并缓存在本地,然后在本地实现负载均衡策略,即根据负载均衡算法直接请求到具体的微服务。Eureka和zuul中默认是Ribbon负载均衡

2.应用场景:Ribbon适合在微服务中RPC远程调用本地服务的负载均衡,比如SpringCloud,Dubbo都是在本地进行负载均衡。

Nginx

1.基于服务端,请求先进入Nginx,然后再进行负载均衡调度。客户端将所有所有请求统一交给nginx,由nginx使用负载均衡算法进行请求转发。

2.应用场景:适合服务器端实现负载均衡的,比如Tomcat,Jetty。

4.4 Ribbon常见的均衡算法

RoundRobinRule:默认的轮询访问策略RandomRule:随机策略WeightedResponseTimeRule:根据响应时间分配权重的策略,相应越快,权重值越大BestAvailableRule:选择并发量小的策略RetryRule:重试策略,在默认500毫秒内选择服务不成功,则使用RoundRobinRule知道获取成功,否则返回失败信息。

更换默认的负载均衡算法,在消费者服务中配置:

microservice-user: #服务提供者服务名称ribbon:NFLoadBalancerRuleClassName: flix.loadbalancer.RandomRule

4.5 实战

思路:开发一个用户信息服务(microservice-user)作为服务提供者,部署两台并注册到EurekaServer中;开发一个用户登陆服务microservice-sso,即服务消费者,并在本地使用Ribbon实现负载均衡,来调用用户服务。

服务提供者

SpringBoot与myBatis整合,开发一个通过用户名查找用户信息的方法作为用户信息服务

1.引入相关依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency><!--web核心依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--mysql数据库驱动--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><!--mybatis--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.1.0</version></dependency>

2.配置文件和启动类

server:port: ${port} #服务端口spring:application:name: microservice-user #指定服务名--用户信息服务# mysql 属性配置datasource:driver-class-name: com.mysql.jdbc.Drivertype: com.alibaba.druid.pool.DruidDataSourceurl: jdbc:mysql://127.0.0.1:3309/store?characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8username: rootpassword: 123456#spring集成Mybatis环境#vo别名扫描包mybatis:type-aliases-package: com.user.demo.user.vomapperLocations: classpath*:mapper/**/*Mapper.xml#executor-type: REUSEeureka:client:registerWithEureka: true #是否将自己注册到Eureka服务中,默认为truefetchRegistry: true #是否从Eureka中获取注册信息,默认为trueserviceUrl: #Eureka客户端与Eureka服务端进行交互的地址defaultZone: http://127.0.0.1:6868/eureka/,http://127.0.0.1:6869/eureka/eurekaServerConnectTimeoutSeconds: 60eurekaServerReadTimeoutSeconds: 60instance:prefer-ip-address: true #将自己的ip地址注册到Eureka服务中ip-address: 127.0.0.1instance-id: ${spring.application.name}:${server.port} #指定实例idlease-expiration-duration-in-seconds: 30 #续约更新时间间隔(默认30秒)lease-renewal-interval-in-seconds: 10 # 续约到期时间(默认90秒)leaseRenewalIntervalInSeconds: 10 #心跳时间

@EnableDiscoveryClient //注册到注册中心并从注册中心获取服务@MapperScan("com.user.demo.user.dao")@SpringBootApplicationpublic class DemoApplication {public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);}}

3.dao与mapper

public interface UserDao {UserVo getUser(String username);}

<mapper namespace="com.user.demo.user.dao.UserDao"><select id="getUser" resultType="UserVo">SELECT uid as id,username,password,name,email,telephone,birthday,sex,stateFROM user WHERE username = #{username}</select></mapper>

4.service

public UserVo getUser(String username){return userDao.getUser(username);}

5.controller

@RestController@RefreshScopepublic class UserController {@Autowiredprivate UserService userService;@GetMapping(value = "user/{username}")public UserVo getUser(@PathVariable("username") String username){return userService.getUser(username);}}

消费者

 本地实现了负载均衡的用户登录服务并调用用户信息服务

1.引入SpringBoot,SpringCloud等相关依赖

2.配置文件

server:port: ${port} #服务端口spring:application:name: microservice-sso #指定服务名---用户登录服务eureka:client:registerWithEureka: true #是否将自己注册到Eureka服务中,默认为truefetchRegistry: true #是否从Eureka中获取注册信息,默认为trueserviceUrl: #Eureka客户端与Eureka服务端进行交互的地址defaultZone: http://127.0.0.1:6868/eureka/,http://127.0.0.1:6869/eureka/ #eureka地址instance:prefer-ip-address: true #将自己的ip地址注册到Eureka服务中ip-address: 127.0.0.1instance-id: ${spring.application.name}:${server.port} #指定实例id

3.启动类中添加RestTemplate,使用**@LoadBalanced**注解

@EnableFeignClients@EnableDiscoveryClient //从eureka server中获取注册列表@SpringBootApplicationpublic class SsoserverApplication {public static void main(String[] args) {SpringApplication.run(SsoserverApplication.class, args);}@Bean // 向Spring容器中定义RestTemplate对象@LoadBalanced //取出服务列表进行负载均衡算法public RestTemplate restTemplate() {return new RestTemplate();}

Service与Controller

@Servicepublic class SsoService {@Autowiredprivate RestTemplate restTemplate;public UserVo checkLogin(String username,String password){String serviceId = "microservice-user"; //用户信息服务的服务名//请求用户服务中查找用户方法的urlString url = "http://" + serviceId + "/user/" + username;UserVo userVo = restTemplate.getForObject(url,UserVo.class);if (userVo!=null){String pw = userVo.getPassword();if (password.equals(pw)){return userVo;}}return null;}}

@RestController@RefreshScopepublic class SsoController {@Autowiredprivate SsoService ssoService;/*** 登录接口* @param username 账号* @param password 密码* @return*/@GetMapping(value = "login/{username}/{password}")public ResultData userLogin(@PathVariable("username") String username, @PathVariable("password") String password) {UserVo userVo = ssoService.checkLogin(username,password);if(userVo == null ){return new ResultData(1,"登录失败",null);}return new ResultData(1,"登录成功",userVo);}

服务提供者和消费者开发完成后,通过动态传入端口启动两台,并注册到EurekaServer中,访问EurekaServer查看微服务信息

访问消费者的url(我的消费者的url端口是8381和8382):http://localhost:8381/login/aaa/aaa或http://localhost:8382/login/aaa/aaa,刷新四次,通过控制台打印的sql发现第1次和第3次 用户服务1打印sql,第2次和第4次用户服务2打印sql,可以看到Ribbon默认的是轮询的负载均衡算法

5 SpringCloud Hystrix 容错保护

在分布式环境中,不可避免的会有会有许多服务依赖项中的某些失败。比如有个服务A调用了服务B,而服务B又调用了服务C,但因为某些原因,服务C扛不住了,这时大量的请求就会在服务C处阻塞。这时调用服务C的服务B因为接受不到C的响应,也会出现阻塞,同理,B阻塞了,调用它的A也会阻塞,因为这些阻塞的请求会消耗系统的IO、线程等资源,所以系统会因为扛不住也崩了,这就是服务雪崩。Hystrix提供的熔断、降级等能解决这一问题,提高系统弹性,避免雪崩。

5.1 认识Hystrix

Spring Cloud Hystrix是基于Netflix的开源框架Hystrix的整合,实现了断路器、线程隔离、信号隔离、Fallback、监控等功能。能够保证系统在一个依赖或者多个依赖出险问题时依然可用。

5.2 熔断和降级

熔断:Hystrix中的断路器模式,可以使用@HystrixCommand注解来标注这个方法达到断路器的效果,这样,在调用这个方法时如果超过指定时间(默认是1000ms,当然也可以自定义,自己对这个注解的属性进行设置),断路器就会中断对这个方法的调用。

降级:当一个方法调用异常时,通过调用另一个方法来给用户一个友好的反馈,比如一个商品查询的服务由于访问量大或其他原因扛不住了,这是就会调用另一个方法,告诉用户“当前人数太多,请稍后再试”。通常使用注解@HystrixCommand(fallbackMethod = “xxx”)来实现降级处理,xxx是降级处理时调用的备用方法。

5.3 实战

1.在上面Ribbon实战的基础上添加Hystrix依赖

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix</artifactId></dependency>

2.在启动类添加@EnableHystrix 注解

在方法上添加注解@HystrixCommand(fallbackMethod = “xxx”),并编写对应的降级处理方法。

开发完后,停掉用户信息服务,再访问用户登录服务就会出现 “网络出错,请稍后再试” 。

6 SpringCLoud Zull 服务网关

服务网关就是在服务的前面设置一道屏障,对要过来的请求做过滤,校验,路由等处理,校验不通过的请求将被拒绝访问,通过的再将它路由到对应的微服务,提高了微服务的安全性。

6.1 认识zull

Spring Cloud Zuul是整合了Netflix公司的Zuul开源项目实现的微服务网关,有请求路由、负载均衡、校验过虑等功能。网关有的功能,zull基本上都有,其中最关键的就是**路由(Router)和过滤(Filter)**了。

6.2 实战

1.新建SpringBoot项目,添加zull依赖。

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-zuul</artifactId></dependency>

2.启动类添加注解@EnableZuulProxy

zull的路由功能

server:port: ${port} #服务端口 这里zull的端口是6677spring:application:name: microservice-api-gateway #zull网关服务名eureka:client:registerWithEureka: true #是否将自己注册到Eureka服务中,默认为truefetchRegistry: true #是否从Eureka中获取注册信息,默认为trueserviceUrl: #Eureka客户端与Eureka服务端进行交互的地址defaultZone: http://127.0.0.1:6868/eureka/,http://127.0.0.1:6869/eureka/instance:prefer-ip-address: true #将自己的ip地址注册到Eureka服务中ip-address: 127.0.0.1instance-id: ${spring.application.name}:${server.port} #指定实例id

查看现在的服务注册中心:

现在注册中心有用户信息服务(microservice-user)登录服务(microservice-sso)

将zull服务注册到EurekaServer中可以获取到注册中心的服务列表,这样以前访问登录服务(microservice-sso)的请求http://localhost:8382/login/aaa/aaa就可以变成http://localhost:6677/microservice-sso/login/aaa/aaa了。

以前访问用户信息服务(microservice-user)的请求http://localhost:8681/user/aaa就可以变成http://localhost:6677/microservice-user/user/aaa了。

配置路由策略

zuul:routes:sso-service: #sso-service登录服务path: /sso/** #配置请求URL的请求规则serviceId: microservice-sso

进行上面的配置 访问路径就变成了http://localhost:6677/sso/login/aaa/aaa,请求就会都被转发到microservice-sso

路径屏蔽

zull可以配置需要屏蔽掉的url路径,只要该请求符合需要屏蔽的url的规则,那么就不能对微服务进行访问。

zuul:ignore-patterns: **/sso/**

*匹配一级路径

** 可以匹配多级路径

这样配置,带有sso的请求就会被屏蔽过滤掉。

服务屏蔽

zuul:ignored-services: '*'routes:microservice-user: /userserver/**

这样配置可以忽略所有代理,只保留自己的配置,现在只能访问用户信息服务,并且只能使用user这种路径来访问

不能访问:

http://localhost:6677/microservice-sso/login/aaa/aaahttp://localhost:6677/microservice-user/login/aaa

能访问

http://localhost:6677/userserver/login/aaa

上面是屏蔽所有,还可以指定屏蔽

zuul:ignored-services: microservice-ssoroutes:user-service: /userserver/**

此时只有用户登录服务被屏蔽掉了,对服务microservice-sso的请求不会成功

能访问,但用户信息服务能正常访问。

http://localhost:6677/userserver/login/aaahttp://localhost:6677/microservice-user/user/aaa

zull的过滤功能

写一个过滤类 继承ZuulFilter

在这里插入代码片@Slf4j@Component //加入到Spring容器public class UserLoginZuulFilter extends ZuulFilter {//具体的业务逻辑@Overridepublic Object run() {RequestContext requestContext = RequestContext.getCurrentContext();HttpServletRequest request = requestContext.getRequest();log.info("Method:{} URI:{}",request.getMethod(),request.getRequestURI());Object token = request.getParameter("loginToken");if (token == null){log.info("loginToken is null");requestContext.setSendZuulResponse(false); //过滤掉该请求,不对其进行路由转发requestContext.setResponseStatusCode(401); //设置返回的错误码x}else {log.info("loginToken is not null");}return null;}// 该过滤器是否需要执行@Overridepublic boolean shouldFilter() {return true;}/*** 过滤器类型* pre:请求前执行* Routing:路由过滤器* Post:在Response 相应之前执行过滤* @return*/@Overridepublic String filterType() {return "pre"; // 设置过滤器类型为:pre}// 设置执行顺序 越小越先执行@Overridepublic int filterOrder() {return 0;}}

访问http://localhost:6677/sso/login/aaa/aaa无法访问,因为没有loginToken,请求被过滤掉,后台日志:

正确访问http://localhost:6677/sso/login/aaa/aaa?loginToken=xxx

7 总结

到这里,初步了解了SpringCloud中的一些组件,并搭建了一个简单的微服务架构:

SpringCloud Eureka 服务发现框架SpringCloud Ribbon 客户端负载均衡器SpringCloud Hystrix 容错保护SpringCloud Zull 服务网关

当然这些只是入门级,而且SpringCloud还有 配置管理Spring Cloud Config 消息总线 Spring Cloud Bus ,Spring Cloud OpenFign等等,后面会继续… …

**源码地址**:>>>github  >>> csdn下载

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。