网站开发语言什么意思,ppt模板免费下载网站有哪些,济南小程序开发,网站的登录注册页面怎么做的分布式系统微服务就是原来臃肿的项目拆分为多个模块互不关联。如#xff1a;按照子服务拆分、数据库、接口#xff0c;依次往下就更加细粒度#xff0c;当然运维也就越来越难受了。分布式则是偏向与机器将诺大的系统划分为多个模块部署在不同服务器上。微服务和分布式就是作…分布式系统微服务就是原来臃肿的项目拆分为多个模块互不关联。如按照子服务拆分、数据库、接口依次往下就更加细粒度当然运维也就越来越难受了。分布式则是偏向与机器将诺大的系统划分为多个模块部署在不同服务器上。微服务和分布式就是作用的“目标不一样”。微服务与Cloud微服务是一种概念spring-cloud是微服务的实现。微服务也不一定必须使用cloud来实现只是微服务中有许多问题如负载均衡、服务注册与发现、路由等等。而cloud则是将这些处理问题的技术整合了。Spring-Cloud 组件EurekaEureka是Netifix的子模块之一Eureka有2个组件一个EurekaServer 实现中间层服务器的负载均衡和故障转移一个EurekaClient它使得与server交互变得简单。Spring-Cloud封装了Netifix公司开发的Eureka模块来实现服务注册和发现。通过Eureka的客户端 Eureka Server维持心跳连接维护可以更方便监控各个微服务的运行。角色关系图Eureka使用客户端dependency
groupIdorg.springframework.cloud/groupId
artifactIdspring-cloud-starter-netflix-eureka-client/artifactId
/dependency
server:
port: 4001
eureka:
client:
serviceUrl:
defaultZone: http://localhost:3000/eureka/ #eureka服务端提供的注册地址 参考服务端配置的这个路径
instance:
instance-id: admin-1 #此实例注册到eureka服务端的唯一的实例ID
prefer-ip-address: true #是否显示IP地址
leaseRenewalIntervalInSeconds: 10 #eureka客户需要多长时间发送心跳给eureka服务器表明它仍然活着,默认为30 秒 (与下面配置的单位都是秒)
leaseExpirationDurationInSeconds: 30 #Eureka服务器在接收到实例的最后一次发出的心跳后需要等待多久才可以将此实例删除默认为90秒spring:
application:
name: server-admin #此实例注册到eureka服务端的name
服务端dependency
groupIdorg.springframework.cloud/groupId
artifactIdspring-cloud-starter-
netflix-eureka-server/artifactId
/dependency
yml文件声明
server:
port: 3000
eureka:
server:
enable-self-preservation: false #关闭自我保护机制
eviction-interval-timer-in-ms: 4000 #设置清理间隔
单位毫秒 默认是60*1000
instance:
hostname: localhost
client:
registerWithEureka: false #不把自己作为一个客户端注册到自己身上
fetchRegistry: false #不需要从服务端获取注册信息
因为在这里自己就是服务端而且已经禁用自己注册了
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka
在SpringBoot 启动项目中加入注解:EnableEurekaServer
就可以启动项目了访问对应地址就可以看到界面。
Eureka 集群服务启动后Eureka Server会向其他服务server 同步当消费者要调用服务提供者则向服务注册中心获取服务提供者的地址然后将提供者的地址缓存到本地下次调用时候直接从本地缓存中获取yml 服务端server:
port: 3000
eureka:
server:
enable-self-preservation: false #关闭自我保护机制
eviction-interval-timer-in-ms: 4000 #设置清理间隔
单位毫秒 默认是60*1000
instance:
hostname: eureka3000.com
client:
registerWithEureka: false #不把自己作为一个客户端
注册到自己身上
fetchRegistry: false #不需要从服务端获取注册信息
因为在这里自己就是服务端而且已经禁用自己注册了
serviceUrl:
defaultZone: http://eureka3001.com:3001/eureka,
http://eureka3002.com:3002/eureka
(这里不注册自己注册到其他服务上面以为会同步。)
yml 客户端server:
port: 4001
eureka:
client:
serviceUrl:
defaultZone:http://localhost:3000/eureka/,http://
eureka3001.com:3001/eureka,http://eureka3002.com:3 002
/eureka #eureka服务端提供的注册地址 参考服务端配置的这个路径
instance:
instance-id: admin-1 #此实例注册到eureka服务端的唯一的实例ID
prefer-ip-address: true #是否显示IP地址
leaseRenewalIntervalInSeconds: 10 #eureka客户需要多长时间发
送心跳给eureka服务器表明它仍然活着,默认为30 秒 (与下面配置的单位都是秒)
leaseExpirationDurationInSeconds: 30 #Eureka服务器在
接收到实例的最后一次发出的心跳后需要等待多久才可以将此实例删除默认为90秒spring:
application:
name: server-admin #此实例注册到eureka服务端的name
CAP定理CConsistency 一致性
AAvailability 可用性
PPartition tolerance 分区容错性
这三个指标不能同时达到
Partition tolerance分区容错性大多数分布式系统都部署在多个子网络。每一个网络是一个区。区间的通信是可能失败的如一个在本地一个在外地他们之间是无法通信的。分布式系统在设计的时候必须要考虑这种情况。Consistency一致性写操作后的读取必须返回该值。如服务器A1和服务器A2现在发起操作将A1中V0改为V1用户去读取的时候读到服务器A1得到V1如果读到A2服务器但是服务器还是V0读到的数据就不对这就不满足一致性。所以让A2返回的数据也对的让A1给A2发送一条消息把A2的V0变为V1这时候不管从哪里读取都是修改后的数据。Availability可用性就是用户只要给出请求就必须回应不管是本地服务器还是外地服务器只要接收到就必须做出回应不管数据是否是最新必须做出回应负责就不是可用性。C与A矛盾一致性和可用性不能同时成立存在分区容错性通信可能失败。如果保证一致性A1在写操作时A2的读写只能被锁定只有等数据同步了才能读写在锁定期间是不能读写的就不符合可用性。如果保持可用性那么A2就不会被锁定所以一致性就不能成立。综上 无法做到一致性和可用性所以系统在设计的时候就只能选其一。Eureka与ZookeeperZookeeper遵循的是CP原则保持了一致性所以在master节点因为网络故障与剩余“跟随者”接点失去联系时会重新选举“领导者”选取“领导者”大概会持续30-120s的时间且选举的时候整个zookeeper是不可用的。导致在选举的时候注册服务瘫痪。Eureka在设计的时候遵循AP可用性。Eureka各个接点是公平的没有主从之分down掉几个几点也没问题其他接点依然可以支持注册只要有一台Eureka在注册就可以用只不过查询到的数据可能不是最新的。Eureka有自我保护机制如果15分钟之内超过85%接点都没有正常心跳那么Eureka认为客户端与注册中心出现故障此时情况可能是Eureka不在从注册列表移除因为长时间没有瘦到心跳而过期的服务。Eureka仍然能够接收注册和查询但不会同步到其他接点。当网络稳定后当前的 实例注册信息会更新到其他接点。ibbonrebbon主要提供客户端的负载均衡提供了一套完善的客户端的配置。Rebbin会自动帮助你基于某种规则如简单的轮询随机链接等。服务端的负载均衡是一个url通过一个代理服务器然后通过代理服务器策略轮询随机 权重等等反向代理到你的服务器。客户端负载均衡是通过一个请求在客户端已经声明了要调用那个服务然后通过具体算法来完成负载均衡。ibbon使用引入依赖Eureka以及把Ribbon集成在里面。使用Ribbon只有在RestTemplate上面加入LoadBalanced注解。Feign负载均衡feign是一个声明式的webService客户端使用feign会让编写webService更简单就是定义一个接口加上注解。feign是为了编写java http客户端更加简单在RibbonRestTemplate此基础上进一步封装简化了使用Spring Cloud Ribbon时自动封装服务调用客户端的开发量。Feign使用引入依赖
dependency
groupIdorg.springframework.cloud/groupId
artifactIdspring-cloud-starter-openfeign/artifactId
/dependency
在启动类上加EnableFeignClients
然后在接口上加FeignClient(SERVER-POWER)注解其中参数就是服务的名字。
Feign集成Ribbon利用Ribbon维护服务列表信息融合了Ribbon的负载均衡配置与Ribbon不同的是Feign只需要定义服务绑定接口以声明的方式实现简答的服务调用。hystrix断路器是一种用于处理分布式系统延迟和容错的开源库。在分布式系统中许多依赖不可避免的会调用失败比如超时、异常等断路器保证出错不会导致整体服务失败避免级联故障。断路器其实就是一种开关设置类似保险丝像调用方返回一个符合预期的、可处理的备选响应而不是长时间等待或者抛出无法处理的异常保证服务调用方线程不会被长时间 不必要占用从而避免了在分布式系统中蔓延乃至雪崩。微服务中 client-微服务A-微服务B-微服务C-微服务D,其中微服务B异常了所有请求微服务A的请求都会卡在B这里就会导致线程一直累积在这里那么其他微服务就没有可用线程导致整个服务器雪崩。针对这方案有 服务限流、超时监控、服务熔断、服务降级降级 超时降级就是服务响应过长 或者不可用了就是服务调用不了了我们不能把错误信息返回出来或者长时间卡在哪里所以要准备一个策略当发生这种问题我们直接调用这个方法快速返回这个请求不让他一直卡在那。要在调用方做降级要不然那个微服务都down掉了在做降级就没有意义。引入hystrix依赖dependency
groupIdorg.springframework.cloud/groupId
artifactIdspring-cloud-starter-netflix-hystrix/artifactId
/dependency
在启动类上加入EnableHystrix 或者EnableCircuitBreaker。
RequestMapping(/feignPower.do)
HystrixCommand(fallbackMethod fallbackMethod)
public Object feignPower(String name){
return powerServiceClient.power();
}
fallbackMethod
public Object fallbackMethod(String name){
System.out.println(name);
return R.error(降级信息);
}
这里的降级信息具体内容根据业务需求来比如返回一个默认的查询信息等等。
hystrix有超时监听当你请求超过1秒 就会超时这个是可以配置的
这里的降级信息具体内容根据业务需求来比如返回一个默认的查询信息等等。hystrix有超时监听当你请求超过1秒 就会超时这个是可以配置的降级什么用第一他可以监听服务有没有超时。第二报错了他这里直接截断了没有让请求一直卡在这个。其实降级当你系统迎来高并发的时候这时候发现系统马上承载不了这个大的并发 可以先关闭一些不重要 的微服务就是在降级方法返回一个比较友好的信息把资源让出来给主服务其实就是整体资源不够用了忍痛关闭某些服务待过渡后再打开。熔断限流熔断就像生活中的跳闸比如电路故障了为了防止事故扩大这里切断你的电源以免意外发生。当一个微服务调用多次hystrix就会采取熔断 机制不在继续调用你的方法会默认短路5秒后试探性的先关闭熔断机制如果在这时候失败一次会直接调用降级方法一定程度避免雪崩限流限制某个微服务使用量如果线程占用超过了超过的就会直接降级该次调用。Feign整合hystrixfeign默认支持hystrix需要在yml配置中打开。
feign:
hystrix:
enabled: true降级方法
FeignClient(value SERVER-POWER, fallback PowerServiceFallBack.class)
public interface PowerServiceClient {RequestMapping(/power.do)
public Object power(RequestParam(name) String name);
}在feign客户端的注解上 有个属性叫fallback 然后指向一个类 PowerServiceClient
Component
public class PowerServiceFallBack implements PowerServiceClient {
Override
public Object power(String name) {
return R.error(测试降级);
}
}
Zuul 网关zuul包含了对请求的路由和过滤两个主要功能路由是将外部请求转发到具体的微服务实例上。是实现统一入口基础而过滤器功能负责对请求的处理过程干预是实现请求校验等功能。Zuul与Eureka进行整合将zuul注册在Eureka服务治理下同时从Eureka获取其他服务信息。zuul分服务最终还是注册在Eureka上路由dependency
groupIdorg.springframework.cloud/groupId
artifactIdspring-cloud-starter-netflix-zuul/artifactId
/dependency
dependency
groupIdorg.springframework.cloud/groupId
artifactIdspring-cloud-starter-netflix-eureka-client/artifactId
/dependency
最后要注册在Eureka上所以需要引入eureka依赖
YML
server:
port: 9000
eureka:
client:
serviceUrl:
defaultZone: http://localhost:3000/eureka/ #eureka服务端提供的注册地址 参考服务端配置的这个路径
instance:
instance-id: zuul-0 #此实例注册到eureka服务端的唯一的实例ID
prefer-ip-address: true #是否显示IP地址
leaseRenewalIntervalInSeconds: 10 #eureka客户需要多长时间发送心跳给eureka服务器表明它仍然活着,默认为30 秒 (与下面配置的单位都是秒)
leaseExpirationDurationInSeconds: 30 #Eureka服务器在接收到实例的最后一次发出的心跳后需要等待多久才可以将此实例删除默认为90秒spring:
application:
name: zuul #此实例注册到eureka服务端的name
启动类 EnableZuulProxy在实际开发当中我们肯定不会/server-power这样通过微服务调用
可能只要一个/power就好了
zuul:
routes:
mypower:
serviceId: server-power
path: /power/**
myorder:
serviceId: server-order
path: /order/**
注意/**代表是所有层级 /* 是代表一层。
一般我们会禁用服务名调用
ignored-servicesserver-order 这样就不能通过此服务名调用
不过这个配置如果一个一个通微服务名字设置太复杂
一般禁用服务名 ignored-services“*”
有时候要考虑到接口调用需要一定的规范比如调用微服务URL需要前缀/api可以加上一个prefix
prefix/api 在加上strip-prefix: false /api前缀是不会出现在路由中
zuul:
prefix: /api
ignored-services: *
stripPrefix: false
routes:
product:
serviceId: server-product
path: /product/**
order:
serviceId: server-order
path: /order/**
过滤器过滤器(filter)是zuul的核心组件zuul大部分功能是通过过滤器实现的zuul中定义了4种标准过滤器类型这些过滤器类型对应与请求的生命周期PRE这种过滤器在请求路由前被调用可利用过滤器进行身份验证记录请求微服务的调试信息等。ROUTING这种过滤器将请求路由到微服务这种过滤器用于构建发送给微服务请求并使用 Apache HttpClient或Netfix Ribbon请求微服务。POST这种过滤器在路由微服务后执行可用来相应添加标准的HTTP Header、收集统计信息和指标、将响应从微服务发送给客户端。ERROR在其他阶段发送错误时执行过滤器继承ZuulFilterComponent
public class LogFilter extends ZuulFilter {
Override
public String filterType() {
return FilterConstants.PRE_TYPE;
}Override
public int filterOrder() {
return FilterConstants.PRE_DECORATION_FILTER_ORDER1;
}Override
public boolean shouldFilter() {
return true;
}Override
public Object run() throws ZuulException {
RequestContext ctx RequestContext.getCurrentContext();
//被代理到的微服务
String proxy (String)ctx.get(proxy);
//请求的地址
String requestURI (String)ctx.get(requestURI);
//zuul路由后的url
System.out.println(proxy/requestURI);
HttpServletRequest request ctx.getRequest();
String loginCookie CookieUtil.getLoginCookie(request);
ctx.addZuulRequestHeader(login_key,loginCookie);
return null;
}
}
由此可知道自定义zuul Filter要实现以下几个方法。filterType返回过滤器类型有pre、route、post、erro等几种取值filterOrder返回一个int值指定过滤器的顺序不同过滤器允许返回相同数字。shouldFilter返回一个boolean判断过滤器是否执行true执行false不执行。run过滤器的具体实现。Spting-Cloud默认为zuul编写并开启一些过滤器。如果要禁用部分过滤器只需在application.yml里设置zuul…disabletrue例如zuul.LogFilter.pre.disabletruezuul也整合了了hystrix和ribbon的 提供降级回退继承FallbackProvider 类 然后重写里面的方法。