微服务框架 -- SpringCloud

SpringCloud

官网解释为:spring Cloud为开发人员提供了快速构建分布式系统中的一些常见模式的工具(例如配置管理、服务发现、断路器、智能路由、微代理、控制总线、一次性令牌、全局锁、领导层选举、分布式会话、集群状态)。分布式系统的协调导致了锅炉板模式,使用Spring Cloud开发人员可以快速建立实现这些模式的服务和应用程序。它们在任何分布式环境中都能很好地工作,包括开发人员自己的笔记本电脑、裸机数据中心和云计算等托管平台。首先SpringCloud是基于SpringBoot开发的。

一、服务注册于发现(Eureka)

springCloud Netflix自带组件Eureka作为注册中心,实现 服务协调、负载均衡、容错、路由等

创建EurekaServer项目开启注册中心:

 <parent> 
  <groupId>org.springframework.boot</groupId> 
  <artifactId>spring-boot-starter-parent</artifactId> 
  <version>1.5.2.RELEASE</version> 
  <relativePath /> <!-- lookup parent from repository --> 
 </parent> 
 <properties> 
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 
  <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> 
  <java.version>1.8</java.version> 
 </properties> 
 
 <dependencies> 
  <!--eureka server --> 
  <dependency> 
   <groupId>org.springframework.cloud</groupId> 
   <artifactId>spring-cloud-starter-eureka-server</artifactId> 
  </dependency> 
  <!-- spring boot test --> 
  <dependency> 
   <groupId>org.springframework.boot</groupId> 
   <artifactId>spring-boot-starter-test</artifactId> 
   <scope>test</scope> 
  </dependency> 
 </dependencies> 
<dependencyManagement> 
  <dependencies> 
   <dependency> 
    <groupId>org.springframework.cloud</groupId> 
    <artifactId>spring-cloud-dependencies</artifactId> 
    <version>Dalston.RC1</version> 
    <type>pom</type> 
    <scope>import</scope> 
   </dependency> 
  </dependencies> 
 </dependencyManagement> 
 

设置配置文件 :application.yml

server:
   port: 8888
eureka:
   instance:
     hostname: localhost   
   client:
     registerWithEureka: false
     fetchRegistry: false
     serviceUrl:
       defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ 

启动Eureka:

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

二、创建一个服务提供者:member-service

配置文件:application.yml 将该服务提供者注册到注册中心Eureka

eureka: 
  client: 
    serviceUrl: 
      defaultZone: http://localhost:8888/eureka/ 
server: 
  port: 8762 
spring: 
  application:
     name: member-service

服务接口:

@RestController 
public class MemberController { 
 
 @RequestMapping("/getUserList") 
 public List<String> getUserList() { 
  List<String> listUser = new ArrayList<String>(); 
  listUser.add("zhangsan"); 
  listUser.add("lisi"); 
  listUser.add("wangwu"); 
  return listUser; 
 } 
 
} 
 

开启服务:

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

三、服务消费者 order-service

配置文件:application.yml

eureka: 
  client: 
    serviceUrl: 
      defaultZone: http://localhost:8888/eureka/ 
server: 
  port: 8764 
spring: 
  application:
     name: order-service

编写service,调用服务生产者:

@Service 
public class MemberService { 
 @Autowired 
 RestTemplate restTemplate; 
 
 public List<String> getOrderByUserList() { 
  return restTemplate.getForObject("http://service-member/getUserList", List.class); 
 }  
} 
 

启动项目:

@EnableEurekaClient 
@SpringBootApplication 
public class AppOrder { 
 
 public static void main(String[] args) { 
  SpringApplication.run(AppOrder.class, args); 
 } 
 
//配置Bean属性,往IOC里面注入一个Bean,通过@LoadBalance表明开启负载均衡
 @Bean 
 @LoadBalanced 
 RestTemplate restTemplate() { 
  return new RestTemplate(); 
 } 
 
} 
 
 

四、服务治理之负载均衡 - ribbon (Fegin默认集成)

Ribbon类似于Nginx反向代理,通过负载均衡算法将请求路由到指定的服务上。使用就是采用restTemplate通过@LoadBalanced注解来实现开启负载均衡功能

使用Fegin实现只需要在暴露接口的类上加注解@FeginCilent("服务名")即可,Fegin默认集成Rebbon,类似于Dubbo的暴露服务,但是Fegin是一个声明式的http客户端,Dubbo是基于私有二进制协议

五、路由网关-Zuul

Zuul 的主要功能是路由转发和过滤器。路由功能是微服务的一部分,比如/api/user 转发 到 user 服务,/api/shop 转发到 shop 服务。zuul 默认和 Ribbon 结合实现了负载均衡 的功能, 类似于 nginx 转发。

配置文件配置:

eureka: 
  client: 
    serviceUrl: 
      defaultZone: http://localhost:8888/eureka/ 
server: 
  port: 8769 
spring: 
  application: 
    name: service-zuul 
zuul: 
  routes: 
    api-a: 
      path: /api-member/** 
      service-id: service-member 
    api-b: 
      path: /api-order/**
       service-id: service-order 

发送请求 http://127.0.0.1:8769/api-member/getMemberAll  转发到 http://127.0.0.1:8762/getMemberAll 开启网关 @EnableZuulProxy 

服务过滤:

@Component 
public class MyFilter extends ZuulFilter { 
 
 private static Logger log = LoggerFactory.getLogger(MyFilter.class); 
 
 @Override 
 public String filterType() { 
  return "pre";  
 } 
 
 @Override 
 public int filterOrder() { 
  return 0; 
 } 
 
 public boolean shouldFilter() { 
  return true; 
 } 
 
 public Object run() { 
  RequestContext ctx = RequestContext.getCurrentContext(); 
  HttpServletRequest request = ctx.getRequest(); 
  log.info(String.format("%s >>> %s", request.getMethod(), 
  request.getRequestURL().toString())); 
  Object accessToken = request.getParameter("token"); 
  if (accessToken != null) { 
   return null; 
  } 
  log.warn("token is empty"); 
  ctx.setSendZuulResponse(false); 
  ctx.setResponseStatusCode(401); 
  try { 
   ctx.getResponse().getWriter().write("token is empty"); 
  } catch (Exception e) { 
  } 
  return null; 
 
 } 
} 

六、服务治理,解决服务器雪崩应对策略  -- 断路器(Hystrix)

          在微服务架构中,我们将业务拆分成一个个的服务,服务与服务之间可以相互调用 (RPC)。为了保证其高可用,单个服务又必须集群部署。由于网络原因或者自身的原因, 服务并不能保证服务的 100%可用,如果单个服务出现问题,调用这个服务就会出现网络延 迟,此时若有大量的网络涌入,会形成任务累计,导致服务瘫痪,甚至导致服务“雪 崩”。为了解决这个问题,就出现断路器模型。 
          Hystrix 是一个帮助解决分布式系统交互时超时处理和容错的类库, 它同样拥有保护系统 的能力.
          分布式系统中经常会出现某个基础服务不可用造成整个系统不可用的情况, 这种现象被称 为服务雪崩效应. 为了应对服务雪崩, 一种常见的做法是手动服务降级. 而 Hystrix 的出 现,给我们提供了另一种选择. 

1、熔断设计:

(1)熔断请求判断机制算法:使用无锁循环队列计数,每个熔断器默认维护 10 个bucket,每 1 秒一个 bucket,每个 blucket 记录请求的成功、失败、超时、拒绝的状态,默认错误超过 50%且 10 秒内超过 20 个请求进行中断拦截。 
(2)熔断恢复:对于被熔断的请求,每隔 5s 允许部分请求通过,若请求都是健康的(RT<250ms)则对请求健康恢复。  
(3)熔断报警:对于熔断的请求打日志,异常请求超过某些设定则报警 

2、隔离设计:

(1)线程池隔离模式:使用一个线程池来存储当前的请求,线程池对请求作处理,设置任务返回处理超时时间,堆积的请求堆积入线程池队列。这种方式需要为每个依赖的服务申请线程池,有一定的资源消耗,好处是可以应对突发流量(流量洪峰来临时,处理不完可将数据存储到线程池队里慢慢处理) 
(2)信号量隔离模式:使用一个原子计数器(或信号量)来记录当前有多少个线程在运行,请求来先判断计数器的数值,若超过设置的最大线程个数则丢弃改类型的新请求,若不超过则执行计数操作请求来计数器+1,请求返回计数器-1。这种方式是严格的控制线程且立即返回模式,无法应对突发流量(流量洪峰来临时,处理的线程超过数量,其他的请求会直接返回,不继续去请求依赖的服务) 

3.超时设计:

等待超时:在任务入队列时设置任务入队列时间,并判断队头的任务入队列时间是否大于超时时间,超过则丢弃任务。 
运行超时:直接可使用线程池提供的 get 方法 

服务降级使用:

①使用rest方式的断路器,当服务不可用时不会出现异常,降级也就是将原来的服务不可用时回调一个方法类似于 -- 前台返回“连接人数过多,请稍后是在试!”

//Rest请求方式接口改造 
@HystrixCommand(fallbackMethod = "orderError") 
public List<String> getOrderUserAll() { 
return restTemplate.getForObject("http://service-member/getMemberAll", List.class); 
} 
 
public List<String> orderError() { 
 List<String> listUser = new ArrayList<String>(); 
 listUser.add("not orderUser list"); 
 return listUser; 
}

然后启动项目,启动类和之前一样只是需要在原来的类上面加@EnableHystrix注解来启动断路器,其中@HystrixCommand表示服务发生错误的回调方法

②Fegin实现断路器,在给服务进行代理的同时进行负载均衡,设置回调函数,当出现问题时调用回调函数

@FeignClient(value="service-member",fallback=MemberFeignService.class) 
public interface MemberFeign {  

    @RequestMapping("/getMemberAll")  
    public List<String> getOrderByUserList(); 
} 

   
 @Component 
 public class MemberFeignService implements MemberFeign { 
 
 public List<String> getOrderByUserList() { 
  List<String> listUser = new ArrayList<String>(); 
  listUser.add("not orderUser list"); 
  return listUser; 
 } 
} 

修改配置文件,在配置文件中添加即可

fegin: 
    hystrix: 
        enable: true

SpringCloud基础内容完毕,更多请参照SpringCloud官方文档!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值