㈠ Spring Cloud微服务体系的组成
Netflix Eureka是Spring Cloud服务注册发现的基础组件 Eureka提供RESTful风格(HTTP协议)的服务注册与发现 Eureka采用C/S架构,Spring Cloud内置客户端 启用应用,访问 http://localhost:8761 Eureka客户端开发要点 maven依赖spring-cloud-starter-netflix-eureka-client application.yml 配置eureka.client.service-url.defaultZone 入口类增加@EnableEurekaClient 先启动注册中心,在启动客户端,访问 localhost:8761查看eureka注册中心,看到客户端注册 Eureka名词概念 Register – 服务注册, 向Eureka进行注册登记 Renew – 服务续约,30秒/次心跳包健康检查.90秒未收到剔除服务 Fetch Registries – 获取服务注册列表,获取其他微服务地址 Cancel – 服务下线, 某个微服务通知注册中心暂停服务 Eviction – 服务剔除,90秒未续约,从服务注册表进行剔除 Eureka自我保护机制 Eureka在运行期去统计心跳失败率在15分钟之内是否低于 85% 如果低于 85%,会将这些实例保护起来,让这些实例不会被剔除 关闭自我保护:eureka.服务实例. enable-self-preservation: false PS: 如非网络特别不稳定,建议关闭 Eureka高可用配置步骤 服务提供者defaultZone指向其他的Eureka 客户端添加所有Eureka 服务实例 URL Actuator自动为微服务创建一系列的用于监控的端点 Actuator在SpringBoot自带,SpringCloud进行扩展 pom.xml依赖spring-boot-starter-actuator RestTemplate + @LoadBalanced 显式调用 OpenFeign 隐藏微服务间通信细节 Ribbon是RestTemplate与OpenFeign的通信基础 Feign是一个开源声明式WebService客户端,用于简化服务通信 Feign采用“接口+注解”方式开发,屏蔽了网络通信的细节 OpenFeign是SpringCloud对Feign的增强,支持Spring MVC注解 1.新建Spring boot Web项目,application name 为 proct-service 在pom.xml中引入依赖 spring-cloud-starter-alibaba-nacos-discovery作用为向Nacos server注册服务。 spring-cloud-starter-openfeign作用为实现服务调用。 2.修改application.yml配置文件 3.在启动类上添加@EnableDiscoveryClient、@EnableFeignClients注解 4.编写OrderClient Interface 注:/api/v1/order/test 会在下面order-service声明。 OrderClient.java 5.编写Controller和service ProctController.java ProctService.java 1.OpenFeign开启通信日志 基于SpringBoot的logback输出,默认debug级别 设置项:feign.client.config.微服务id.loggerLevel 微服务id:default代表全局默认配置 2.通信日志输出格式 NONE: 不输出任何通信日志 BASIC: 只包含URL、请求方法、状态码、执行时间 HEADERS:在BASIC基础上,额外包含请求与响应头 FULL:包含请求与响应内容最完整的信息 3.OpenFeign日志配置项 LoggerLevel开启通信日志 ConnectionTimeout与ReadTimeout 利用httpclient或okhttp发送请求 1.OpenFeign通信组件 OpenFeign基于JDK原生URLConnection提供Http通信 OpenFeign支持Apache HttpClient与Square OkHttp SpringCloud按条件自动加载应用通信组件 2.应用条件 Maven引入feign-okhttp或者feign-httpclient依赖 设置feign.[httpclient|okhttp].enabled=true POST方式传递对象使用@RequestBody注解描述参数 GET方式将对象转换为Map后利用@RequestParam注解描述 雪崩效应:服务雪崩效应产生与服务堆积在同一个线程池中,因为所有的请求都是同一个线程池进行处理,这时候如果在高并发情况下,所有的请求全部访问同一个接口,这时候可能会导致其他服务没有线程进行接受请求,这就是服务雪崩效应效应。 服务熔断:熔断机制目的为了保护服务,在高并发的情况下,如果请求达到一定极限(可以自己设置阔值)如果流量超出了设置阈值,让后直接拒绝访问,保护当前服务。使用服务降级方式返回一个友好提示,服务熔断和服务降级一起使用。 1.Hystrix熔断器 Hystrix(豪猪)是Netflix开源的熔断器组件,用于为微服务提供熔断机制预防雪崩,保护整体微服务架构的健康 2.Hystrix功能 预防微服务由于故障,请求长时间等待导致Web容器线程崩溃 提供故障备选方案,通过回退(fallback)机制提供”服务降级” 提供监控仪表盘,实时监控运行状态 3.Hystrix 熔断器工作原理 服务的健康状况 = 请求失败数 / 请求总数. 熔断器开关由关闭到打开的状态转换是通过当前服务健康状况和设定阈值比较决定的. 当熔断器开关关闭时, 请求被允许通过熔断器. 如果当前健康状况高于设定阈值, 开关继续保持关闭. 如果当前健康状况低于 设定阈值, 开关则切换为打开状态. 当熔断器开关打开时, 请求被禁止通过. 当熔断器开关处于打开状态, 经过一段时间后, 熔断器会自动进入半开状态, 这时熔断器只允许一个请求通过. 当该请求调用 成功时, 熔断器恢复到关闭状态. 若该请求失败, 熔断器继续保持打开状态, 接下来的请求被禁止通过. 熔断器的开关能保证服务调用者在调用异常服务时, 快速返回结果, 避免大量的同步等待. 并且熔断器能在一段时间后继续侦测请求执行结果, 提供恢复服务调用的可能. 4.什么情况下会触发服务降级 FAILURE: 执行失败,抛出异常 TIMEOUT:执行超时(默认1秒) SHORT_CIRCUITED:熔断器状态为Open THREAD_POOL_REJECTED:线程池拒绝 SEMAPHORE_REJECTED:信号量拒绝 5.使用Hystrix步骤 1.引入pom文件依赖 6.OpenFeign与Hystrix整合 OpenFeign中使用Hystrix OpenFeign内置Hystrix,feign.hystrix.enable开启即可 feign: hystrix: enabled: true 在@FeignClient增加fallback属性说明Fallback类 @FeignClient(name="message-service",fallback = MessageServiceFallback.class) public interface MessageService { @GetMapping("/sendsms") public CallbackResult sendSMS(@RequestParam("mobile") String mobile , @RequestParam("message") String message); } Fallback类要实现相同接口,重写服务降级业务逻辑 @Component public class MessageServiceFallback implements MessageService { @Override public CallbackResult sendSMS(String mobile, String message) { return new CallbackResult("INVALID_SERVICE","消息服务暂时无法使用,短信发送失败"); } } 7.Hystrix超时设置8.部署Hystrix Dashboard监控 Hystrix Client依赖hystrix-metrics-event-stream Hystrix Client注册HystrixMetricsStreamServlet 监控微服务依赖spring-cloud-starter-netflix-hystrix-dashboard 监控微服务利用@EnableHystrixDashboard开启仪表盘 9.Hystrix熔断设置 产生熔断的条件: 当一个Rolling Window(滑动窗口)的时间内(默认:10秒),最近20次调用请求,请求错误率超过50%,则触发熔断5秒,期间快速失败。 TIPS: 如10秒内未累计到20次,则不会触发熔断 Hystrix熔断设置项: 统一访问出入口,微服务对前台透明 安全、过滤、流控等API管理功能 易于监控、方便管理 Netflix Zuul Spring Cloud Gateway Zuul 是Netflix开源的一个API网关, 核心实现是Servlet Spring Cloud内置Zuul 1.x Zuul 1.x 核心实现是Servlet,采用同步方式通信 Zuul 2.x 基于Netty Server,提供异步通信 认证和安全 性能监测 动态路由 负载卸载 静态资源处理 压力测试 Spring Cloud Gateway,是Spring“亲儿子” Spring Cloud Gateway旨在为微服务架构提供一种简单而有效的统一的API路由管理方式 Gateway基于Spring 5.0与Spring WebFlux开发,采用Reactor响应式设计 1.使用三部曲 依赖spring-cloud-starter-netflix-zuul 入口增加 @EnableZuulProxy application.yml 增加微服务映射 2.微服务映射 Spring Cloud Zuul内置Hystrix 服务降级实现接口:FallbackProvider 1.微服务网关流量控制 微服务网关是应用入口,必须对入口流量进行控制 RateLimit是Spring Cloud Zuul的限流组件 https://github.com/marcosbarbero/spring-cloud-zuul-ratelimit RateLimit采用“令牌桶”算法实现限流 2.什么是令牌桶1.Zuul的执行过程 2.Http请求生命周期 1.需要实现ZuulFilter接口 shouldFilter() – 是否启用该过滤器 filterOrder() – 设置过滤器执行次序 filterType() – 过滤器类型:pre|routing|post run() – 过滤逻辑 2.Zuul内置过滤器 3.Zuul+JWT跨域身份验证 1.Spring Cloud Config 2.携程 Apollo 3.阿里巴巴Nacos 1.依赖"spring-cloud-starter-config" 2.删除application.yml,新建bootstrap.yml 3.配置"配置中心"服务地址与环境信息 1、微服务依赖"spring-boot-starter-actuator"; 2、动态刷新类上增加@RefreshScope注解 3、通过/actuator/refresh刷新配置 1、通过加入重试机制、提高应用启动的可靠性; 2、重试触发条件1:配置中心无法与仓库正常通信 3、重试触发条件2:微服务无法配置中心正常通信
㈡ 反应式微服务框架Flower
Flower是一个构建在Akka上的反应式微服务框架,开发者只需要针对每一个细粒度的业务功能开发一个Service服务,并将这些Service按照业务流程进行可视化编排,即可得到一个反应式系统。 Flower既是一个反应式编程框架,又是一个分布式微服务框架。 Flower框架使得开发者无需关注反应式编程细节,即可得到一个反应式系统。 快速上手 Flower框架的主要元素包括:Flower Service(服务)、Flower 流程和Flow容器。Service实现一个细粒度的服务功能,Service之间通过Message关联,前一个Service的返回值(Message),必须是后一个Service的输入参数(Message),Service按照业务逻辑编辑成一个Flow(流程),Flower容器负责将前一个Service的返回消息,传递给后一个Service。 安装 Maven Gradle SBT Ivy Flower初始化 Flower使用前需要进行初始化,这里演示最简单的方式。 Flower初始化 定义Flower服务 开发Service类必须实现Flower框架的Service接口或者继承AbstractService基类,在process方法内完成服务业务逻辑处理。 UserServiceA UserServiceB UserServiceC1 服务注册 Flower提供两种服务注册方式:配置文件方式和编程方式。 服务流程编排 Flower框架提供两种服务流程编排方式:配置文件方式和编程方式。 两种编排方式的结果是一样: 调用Flower流程 前面定义了3个Flower服务,并编排了名称为flower_test的服务流程。那么怎么使用它呢? 完整示例 在Flower里面消息是一等公民,基于Flower开发的应用系统是面向消息的应用系统。 消息由Service产生,是Service的返回值;同时消息也是Service的输入。前一个Service的返回消息是下一个Service的输入消息,没有耦合的Service正是通过消息关联起来,组成一个Service流程,并最终构建出一个拥有完整处理能力的应用系统。流程举例: 术语 Flower消息处理模式 消息除了将服务串联起来,构成一个简单的串行流程,还可以组合应用,产生更强大的功能。 消息分叉 消息分叉是指,一个服务输出的消息,可能产生分叉,分发给1个或者多个其他服务。消息分叉后有两种处理方式,全部分发和条件分发。 全部分发 将输出消息分发给全部流程后续服务。后续多个服务接受到消息后,并行执行。这种模式多用于可并行执行的多个子任务,比如用户注册成功后,需要1、将用户数据写入数据库,2、给用户发送激活邮件,3、给用户发送通知短信,4、将新用户注册信息发送给关联产品,实现账户打通。上述4个服务就可以采用消息全部分发模式,接受用户注册消息,并发完成上述4个任务。 要实现消息全部分发,需要在流程中进行配置,所有需要接受前序服务的输出消息的服务都要配置在流程中,如 service1是前序服务,service2和service3是后继服务。 如果service2和service3的class定义中,实现Service接口的声明中指定了泛型,则泛型类型必须是service1的输出类型或者其父类。 Service1 Service2 Service3 条件分发 有时候,前一个服务产生的消息,根据消息内容和业务逻辑可能会交给后续的某一个服务处理,而不是全部服务处理。比如用户贷款申请,当前服务计算出用户信用等级后,需要根据信用等级判断采用何种贷款方式,或者是拒绝贷款,不同贷款方式和拒绝贷款是不同的服务,这些服务在流程配置的时候,都需要配置为前序服务的后继服务,但是在运行期根据条件决定将消息分发给具体哪个后继服务。 实现条件分发在流程配置上和全部分发一样,所有可能的后继服务都要配置在流程中。具体实现条件分发有如下三种方式。 根据泛型进行分发 后续服务实现接口的时候声明不同的泛型类型,前序服务根据业务逻辑构建不同的消息类型,Flower会根据消息类型匹配对应的服务,只有成功匹配,消息才发送给过去。比如: 构建流程 声明ServiceB接受的消息类型为MessageB ServiceA ServiceB是ServiceA的后续服务,ServiceA收到的消息如果是字符串“b”,就会返回消息类型B,这时候框架就会将消息发送给ServiceB,而不会发送给ServiceC。 在消息中指定后继服务的id进行分发 前序消息实现Condition接口,并指定后继服务的id,如: 一般说来,服务是可复用的,可复用于不同的流程中,但是在不同的流程中后继服务可能是不同的,后继服务的id也是不同的,在服务中写死后续服务id,显然不利于服务的复用。解决方案有两种,一种是在不同的流程中,写一个专门用于分发的服务,也就是处理业务逻辑的服务并不关心消息的分发,只管返回消息内容,但是其后继服务是一个专门用来做消息分发的服务,这个服务没有业务逻辑,仅仅实现Condition接口根据消息内容指定后继服务。 另一种是使用框架内置服务ConditionService进行消息分发 使用框架内置服务ConditionService进行消息分发 ConditionService是一个通用的消息分发服务, 服务serviceE要将消息根据条件分发给serviceF或者serviceG,流程配置如上,中间加入serviceCondition进行适配。 serviceCondition的服务注册方法为 com.ly.train.flower.common.service.ConditionService为框架内置服务 这种方式中,依然需要在serviceCondition的前驱服务serviceE中设置返回消息的condition,但是不必设置后续服务的id,只需要设置后续服务的顺序号即可。 几种条件分发的代码示例参考/flower.sample/src/main/java/com/ly/train/flower/common/sample/condition/Sample.java 消息聚合 对于全部分发的消息分叉而言,通常目的在于使多个服务能够并行执行,加快处理速度。通常还需要得到这些并行处理的服务的全部结果,进行后续处理。 在Flower中,得到多个并行处理服务的结果消息,称为消息聚合。实现方式为,在流程中,配置需要聚合的多个消息的后续服务为com.ly.train.flower.common.service.AggregateService,这是一个框架内置服务,负责聚合多个并行服务产生的消息,将其封装到一个Set对象中返回。 如流程 这里的service5就是一个消息聚合服务,负责聚合并行的service2和service3产生的消息,并把聚合后的Set消息发送给service4. 服务配置如下,service5配置为框架内置服务AggregateService。 service4负责接收处理聚合后的消息,从Set中取出各个消息,分别处理。 消息回复 Flower中的消息全部都是异步处理,也就是服务之间不会互相阻塞等待,以实现低耦合、无阻塞、高并发的响应式系统。Flower流程调用者发送出请求消息以后,消息在流程中处理,调用者无需阻塞等待处理结果,可以继续去执行其他的计算任务。 和传统的命令式编程不同,通常流程的发起调用者并不是流程处理结果的最终接受者,比如对于web开发,流程的发起者通常是一个servlet,但是真正接受处理结果的是用户端浏览器或者App,流程中的服务可以直接发送处理结果给用户端,而不必通过servlet。也就是调用发起者servlet无需等待流程服务的最终处理结果,将用户请求发送到流程中后,不必阻塞等待处理,可以立即获取另一个用户的请求继续进行处理。 但是Flower也支持调用者阻塞等待消息处理结果,消息回复模式可以使流程调用者得到流程处理的最终结果消息。可参考代码示例 /flower.sample/src/main/java/com/ly/train/flower/common/sample/textflow/Sample.java Flower web开发模式 Flower集成Servlet3的web开发模式 Flower支持Servlet3的异步模式,请求处理线程在调用Flower流程,并传入AsyncContext对象后立即释放。 代码示例参考/flower.sample/src/main/java/com/ly/train/flower/common/sample/web/async/AsyncServlet.java 开发支持Servlet3的Flower服务,需要实现框架的Service接口,在方法 Object process(T message, ServiceContext context) throws Exception;中,Flower框架会传入一个Web对象,通过context.getWeb()得到Web对象,用以获得请求参数和输出处理响应结果。 Flower集成Spring boot的web开发模式 Flower支持Spring boot开发,在项目中依赖flower.web,实现框架中的Service接口和InitController接口。 初始化@BindController注解需要的参数,在编译过程中自动由flower.web枚举@BindController注解, 生成Spring boot需要的Controller。 注意: flower.web利用annotation为Service生成spring boot所需的Controller类。这个生成过程在程序编译的时候完成,如果IDE环境不支持热编译,需要在命令行执行mvn install生成代码。 代码示例参考/flower.sample/src/main/java/com/ly/train/flower/common/sample/springboot 使用Flower框架的开发建议 Flower分布式部署架构开发流程 一. 启动Flower.center注册中心 二. 开发Flower Service,启动业务服务Flower容器,自动向注册中心注册服务 三. 开发Flower web网关,启动Flower网关服务,编排流程 一. 注册中心 Flower.center基于spring-boot开发,通过打包成fat-jar后通过命令行启动即可。 Flower注册中心启动入口/flower.center/src/main/java/com/ly/train/flower/center/CenterApplication.java Flower注册中心启动命令java -jar flower.center-0.1.2.jar 二. 启动业务Flower容器 Flower部署支持Flower容器和Spring容器,下面的例子基于spring-boot演示 2.1 创建配置文件flower.yml 2.2 配置FlowerFactory 2.3 开发flower服务 2.4 创建启动类 三. 启动网关服务器,编排流程 3.1 创建flower.yml 3.2 配置FlowerFactory 3.3 开发Flower服务 3.4 开发网关Controller 3.5 启动类 实例项目细节 flower分布式实例 https://github.com/leeyazhou/flower.showcase.git 核心概念 FlowerFactory 使用默认的FlowerFactory 按需创建自己的FlowerFactory,配置文件路径默认读取classpath:flower.yml,配置文件内容格式为yaml风格,详情查看配置信息。 获取FlowerFactory之后,就可以使用它提供的接口: FlowRouter流程路由器,创建流程之后,通过FlowerFactory可以创建出对应的路由器,之后便可以进行服务的调用了。 分布式 Flower.yml配置信息 了解关于Flower的内部设计,有助于你更好地利用Flower开发一个反应式系统。 Flower core模块(进程内流式微服务框架)设计 Flower基于Akka的Actor进行开发,将Service封装到Actor里面,Actor收到的消息作为参数传入Service进行调用,Service的输出发送给后续Actor作为Service的输入。 Flower核心类Flower初始化及调用时序服务流程初始化 消息流处理 Flower的核心设计不过如此。但是由此延伸出来的应用方法和设计模式却和Akka有了极大的不同。 分布式流式微服务框架设计 传统的分布式微服务框架通过远程调用的方式实现服务的解耦与分布式部署,使得系统开发、维护、服务复用、集群部署更加方便灵活,但是这种微服务依然许多不足之处 流式微服务框架Flower致力于构建一种新的微服务架构体系,使用流式计算的架构思想,以一种更加轻量、更易于设计开发、消息驱动、弱依赖,异步并发的技术特点开发实现微服务系统 架构 部署模型Flower将整个应用系统集群统一管理控制,控制中心控制管理集群的所有资源 Agent部署在集群每一台服务器上,负责加载服务实例,并向控制中心汇报状态 代码仓库负责管理服务的java程序包,程序包用assembly打包 控制中心和Agent基于Akka开发,每个服务包装一个actor里面,actor之间负责消息的通信 集群启动与服务部署时序模型注册服务数据结构 服务之间的依赖关系在控制中心编排
㈢ microk8s处理微服务之间的调用
通过在 microk8s上部署授权服务 ,我们基本上走通了微服务通过配置中心服务(config-central)加载配置并启自己的流程。 在microk8s上部署微服务,现在仅剩下一个需要处理的问题,微服务之间通的互相调用。这里我们用我们微服务集群里的base-service 和 diagnose-service来尝试整个流程。 base服务主要提供平台的基础数据,像配置授权服务一样,我们需要写configmap、deployment、service三个yaml配置文件。 整体上与授权服务没多大区别,但又两个地方这次需要特别注意: 1. 标黄的context-path的配置, springboot2.0 需要使用: server.servlet.context-path= xxxx 如果仍沿用1.0的配置, 启动时contexnt将为‘’。 2. 必须正确配置virtualHostName, 这个参数配置,会导致ribbion找不到base服务, 我就因为填写错误,被整了一两天,后来在介绍Ribbon原理的一篇文章里,发现: 从eureka服务获取服务列表,服务集群必须由VipAddress标识 Base服务的Deployment文件,没有什么特别的,和Authorize基本一样: Service文件,我们仍旧定义为Nodeport方便测试: 部署完成后,我们使用port-forward 命令做个端口映射。 microk8s kubectl port-forward pod/baseservice-79946b574d-kqf8x 8000:9043 通过浏览器访问localhost:8000端口,就可以访问服务了。部署完base服务,我们来看看怎么让diagnose服务调用base服务。 1. 需要在diagnose服务的入口,声明@enableEurekaClient 和 @enableFeignClients 2. 建立feign的接口文件 Name 是我们需要需要调用的微服务名,这个名字一定要注意: 1. 都使用小写, 因为k8s对服务名有要求。 2. 这个一定对应的是相应服务的virtualHostName, 否者找不着。 当然需要加载相应的cloud包,最好通过springboot提供的工具生成。 现在需要来写配置文件configmap,这个配置文件与base服务差不多,唯一区别就是标黄的 部分, 确保自动获取打开,另外使用主动加在服务。 通过上面的配置,我们在启动服务就可以看到,baseservice将被从注册中心获取并房子啊serverlist里。 Deployment和service的书写与base服务没有任何区别,这里就省略了。完成部署后,我们通过postman做测试,可以正确返回结果。 Notes: diagnose服务的conext因为没有正确配置,所以IP和端口后直接接了restful请求路径了,这个需要注意。 检查base服务,可以看到,确实调用了接口。 至此,服务间的调用初步走通了,现在我们还需要做一件事,就是将base服务在注册中心注册的IP改为k8s中的服务名称,只需要在configmap中增加如下属性:eureka.instance.ip-address= baseservice 然后,更新配置文件和deployment文件,重启服务。查看base服务注册中的记录,可以看到hostname和ipaddr已经正确显示服务名称。 重新通过postman调用diagnose服务发现,报错,调用base服务没响应。只好重启diagonose服务,查看日志: 启动后,服务列表已经正确填充了base服务:baseservice:9043 现在重新测试接口,正常返回结果。看来需要正确的设置,feign得自动刷新参数,否则发生服务名变化后,本地缓存不能及时清理,会导致无法正常工作。走到这里,基本上在microk8s上部署服务,并实现服务间的调用就完成了。在整个验证过程中,深深地体会了,spring cloud的不好用:虽然看起来简单,但 一不小心就可能配置错误, 而且很多功能其实k8s已经提供,完全可以掠过。 k8s中的服务,已经提供了loadbalance的作用, feign的使用其实已经没有意义。 所以,虽然将旧的虚拟机环境的微服务迁移到k8s上,基本是走通了。但是我们还需要做的更进一步,剔除springcloud的功能。 这样,让开发工程师,从繁杂的配置中解脱出来,完全可以增减团队效率。
㈣ nginx 的配置文件用什么脚本
本文详细介绍了Nginx配置的一些参数说明,为以后的配置提供一定的帮助。有两种方式来通过这些信号去控制 Nginx,第一是通过 logs 目录下的 nginx.pid 查看当前运行的 Nginx 的进程 ID,通过 kill – XXX 来控制 Nginx。AD:WOT2014课程推荐:实战MSA:用开源软件搭建微服务系统检测nginx配置文件是否正确/usr/local/nginx/sbin/nginx -t -c nginx.conf-c 配置文件路径-g Set global directives. (version >=0.7.4)-t 检测文件是否正确不执行-v Print version.-V Print nginx version, compiler version and configure parameters.编译时如果使用了–with-debug编译,还可以使用error_log file [ debug_core| debug_http | debug_event …] 来获得debug信息通过信号对Nginx进行控制Nginx支持下表中的信号:信号名 作用描述TERM, INT 快速关闭程序,中止当前正在处理的请求QUIT 处理完当前请求后,关闭程序HUP 重新加载配置,并开启新的工作进程,关闭就的进程,此操作不会中断请求USR1 重新打开日志文件,用于切换日志,例如每天生成一个新的日志文件USR2 平滑升级可执行程序WINCH 从容关闭工作进程有两种方式来通过这些信号去控制 Nginx,第一是通过 logs 目录下的 nginx.pid 查看当前运行的 Nginx 的进程 ID,通过 kill – XXX <pid> 来控制 Nginx,其中 XXX 就是上表中列出的信号名。如果您的系统中只有一个 Nginx 进程,那您也可以通过 killall 命令来完成,例如运行 killall – s HUP nginx 来让 Nginx 重新加载配置。配置:use [ kqueue | rtsig | epoll | /dev/poll | select | poll ];FreeBSD使用kqueue,Linux选epoll.worker_connections number 每个worker的最大连接数Maxclient = work_processes *worker_connectionsnginx的upstream目前支持4种方式的分配1、轮询(默认)每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。2、weight指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。2、ip_hash每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。3、fair(第三方)按后端服务器的响应时间来分配请求,响应时间短的优先分配。4、url_hash(第三方)按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。代理只需要在nginx的配置文件中增加虚拟主机,然后加入\proxy_pass http://localhost:8000;负载均衡:只需要在http中增加upstream tgcluster {#定义负载均衡设备的Ip及设备状态ip_hash;server 127.0.0.1:9090 down;server 127.0.0.1:8080 weight=2;server 127.0.0.1:6060;server 127.0.0.1:7070 backup;}在需要使用负载均衡的server中增加proxy_pass http://tgcluster/;每个设备的状态设置为:1.down 表示单前的server暂时不参与负载2.weight 默认为1.weight越大,负载的权重就越大。3.max_fails :允许请求失败的次数默认为1.当超过最大次数时,返回proxy_next_upstream 模块定义的错误4.fail_timeout:max_fails次失败后,暂停的时间。5.backup: 其它所有的非backup机器down或者忙的时候,请求backup机器。所以这台机器压力会最轻。nginx支持同时设置多组的负载均衡,用来给不用的server来使用。client_body_in_file_only 设置为On 可以讲client post过来的数据记录到文件中用来做debugclient_body_temp_path 设置记录文件的目录 可以设置最多3层目录location 对URL进行匹配.可以进行重定向或者进行新的代理 负载均衡FASTCGI配置:请将以下内容保存为fastcgi_params文件,保存于/usr/local/nginx/conf下(Ubuntu可保存于/etc/nginx下),他为我们的FastCGI模块设置了基本的环境变量:#fastcgi_paramsfastcgi_param GATEWAY_INTERFACE CGI/1.1;fastcgi_param SERVER_SOFTWARE nginx;fastcgi_param QUERY_STRING $query_string;fastcgi_param REQUEST_METHOD $request_method;fastcgi_param CONTENT_TYPE $content_type;fastcgi_param CONTENT_LENGTH $content_length;fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;fastcgi_param SCRIPT_NAME $fastcgi_script_name;fastcgi_param REQUEST_URI $request_uri;fastcgi_param DOCUMENT_URI $document_uri;fastcgi_param DOCUMENT_ROOT $document_root;fastcgi_param SERVER_PROTOCOL $server_protocol;fastcgi_param REMOTE_ADDR $remote_addr;fastcgi_param REMOTE_PORT $remote_port;fastcgi_param SERVER_ADDR $server_addr;fastcgi_param SERVER_PORT $server_port;fastcgi_param SERVER_NAME $server_name;# PHP only, required if PHP was built with –enable-force-cgi-redirectfastcgi_param REDIRECT_STATUS 200;请特别注意加粗的一行,PHP-CGI特别需要此行信息来确定PHP文件的位置。另外需要在PHP-CGI的配置文件(Ubuntu 上此配置文件位于/etc/php5/cgi/php.ini)中,打开cgi.fix_pathinfo选项:cgi.fix_pathinfo=1;这样php-cgi方能正常使用SCRIPT_FILENAME这个变量。接下来在nginx的配置中针对php文件配置其利用FastCGI进程来执行:server {index index.php;root /usr/local/nginx/html;location ~ .*.php$ {include /usr/local/nginx/conf/fastcgi_params; #请根据自己保存的路径进行设置fastcgi_index index.php;fastcgi_pass 127.0.0.1:9000; #请根据自己的FastCGI绑定的地址和端口进行配置}}通知Nginx重新载入配置:kill -HUP `cat /usr/local/nginx/logs/nginx.pid`Ubuntu用户可以使用init脚本:sudo /etc/init.d/nginx reload然后启动php-cgi -b 127.0.0.1:9000如果出现No input file specified表示SCRIPT_FILENAME设置的有问题。使用lighttpd的 spawn-fcgiget http://www.lighttpd.net/download/lighttpd-1.4.18.tar.bz2 #获取Lighttpd的源码包tar -xvjf lighttpd-1.4.18.tar.bz2cd lighttpd-1.4.18./configure #编译makecp src/spawn-fcgi /usr/local/bin/spawn-fcgi #取出spawn-fcgi的程序下面我们就可以使用 spawn-fcgi 来控制php-cgi的FastCGI进程了/usr/local/bin/spawn-fcgi -a 127.0.0.1 -p 9000 -C 5 -u www-data -g www-data -f /usr/bin/php-cgi参数含义如下-f <fcgiapp> 指定调用FastCGI的进程的执行程序位置,根据系统上所装的PHP的情况具体设置-a <addr> 绑定到地址addr-p <port> 绑定到端口port-s <path> 绑定到unix socket的路径path-C <childs> 指定产生的FastCGI的进程数,默认为5(仅用于PHP)-P <path> 指定产生的进程的PID文件路径-u和-g FastCGI使用什么身份(-u 用户 -g 用户组)运行,Ubuntu下可以使用www-data,其他的根据情况配置,如nobody、apache等
㈤ Spring Cloud
本文中我们主要介绍微服务开发框架——Spring Cloud。尽管Spring Cloud带有”Cloud”的字样,但它并不是云计算解决方案,而是Spring Boot的基础上构建的,用于快速构建分布式系统的通用模式的工具集。
Spring Cloud有以下特点:
由上图可知,Spring Cloud是以 英文单词+SR+数字 的形式命名版本号的。那么英文单词和SR分别表示什么呢? 因为Spring Cloud是一个综合项目,它包含很多子项目。由于子项目也维护着自己的版本号,Spring Cloud采用了这种命名方式,从而避免与子项目的版本混淆。其中英文单词如Edware是伦敦某地铁站名,它们按照字母顺序发行,可以将其理解为主版本的演进。SR表示”Service Release”,一般表示Bug修复。
版本兼容性如下
版本内容
可参考官方文档: https://spring.io/projects/spring-cloud#overview
我的上一篇博客(微服务理论篇)中谈到,对单体应用进行服务拆分得到各个微服务,而这些服务又是相互独立的,那么我们如何知道各个微服务的健康状态、如何知道某个微服务的存在呢?由此、一个拥有服务发现的框架显得尤为重要。这也就是Eureka诞生的原因。
综上,Eureka通过心跳检查、客户端缓存等机制,确保了系统的高可用性、灵活性和可伸缩性。
通过使用Eureka已经实现了微服务的注册与发现。启动各个微服务时,Eureka Client会把自己的网络信息注册到Eureka Server上。似乎一切更美好了一些。然而,这样的架构依然有一些问题,如负载均衡。一般来说,各个微服务都会部署多个实例。那么服务消费者要如何将请求分摊到多个服务提供实例上呢?
如果服务提供者相应非常慢,那么消费者对提供者的请求就会被强制等待,知道提供者响应或超时。在高负载场景下,如果不作任何处理,此类问题可能会导致服务消费者的资源耗竭甚至整个系统崩溃。 微服务架构的应用系统通常包含多个服务层。微服务之间通过网络进行通信,从而支撑起整个应用系统,因此,微服务之间难免存在依赖关系。而这种由于”基础服务故障”导致”级联故障”的现象称为雪崩效应。
如图所示,A最为服务提供者(基础服务),B为A的服务消费者,C和D是B的服务消费者。当A不可用引起了B的不可用,并将不可用像滚雪球一样放大到C和D时,雪崩效应就形成了。 那么Hystrix是如何容错的呢?
以下对该图做个简单讲解:
Zuul作为微服务架构中的微服务网关。微服务架构经过前几个组件的组合,已经有了基本的雏形了,那么我们为什么还要使用微服务网关呢?我们可以想象,一般情况下我们一个业务并不是只调用一个接口就可以完成一个业务需求。 如果让客户端直接与各个微服务通信,会有以下问题:
如图,微服务网关封装了应用程序的内部结构,客户端只须跟网关交互,而无须直接调用特定微服务接口。同时,还有以下优点:
为什么要同一管理微服务配置? 对于传统的单体应用,常常使用配置文件管理所有配置。例如一个Spring Boot 项目开发的单体应用,可以将配置内容放到application.yml文件中。如果需要切换环境,可以设置多个Profile,并在启用应用时指定spring.profile.active={profile}。 而在微服务架构中,微服务的配置管理一般有以下需求:
㈥ 微服务中如何获取配置文件以及多环境切换配置
同关闭系统还原没有关系!同AVAST有关系! windows xp 速度提升和优化指南 Win XP以其华丽的操作画面和稳定的性能成为不少电脑玩家的首选操作系统,但在使用Windows XP的过程中你会发现,随着时间的推移操作系统在速度上是越来越慢了。
㈦ 微服务启用自带tomcat如何配置
自带的程序设置的时候,只需要我们打开服务信息,然后完成服务信息,后台数据加载加载完成,再设置高等参数,处理信息即可。
㈧ 基于docker部署的微服务架构(二): 服务提供者和调用者
前一篇 基于docker部署的微服务架构(一):服务注册中心 已经成功创建了一个服务注册中心,现在我们创建一个简单的微服务,让这个服务在服务注册中心注册。然后再创建一个调用者,调用此前创建的微服务。
新建一个maven工程,修改pom.xml引入 spring cloud 依赖:
在 resources 目录中创建 application.yml 配置文件,在配置文件内容:
这里eureka的注册地址为上一篇中设置的defaultZone。 在 java 目录中创建一个包 demo ,在包中创建启动入口 AddServiceApplication.java
在demo包下新建一个子包controller,在controller子包下创建一个controller对外提供接口。
在服务注册中心已经运行的情况下,运行 AddServiceApplication.java 中的 main 方法,启动微服务。 访问服务注册中心页面 http://localhost:8000 , 可以看到已经成功注册了 ADD-SERVICE-DEMO 服务。
启动第二个实例,修改端口为 8101 ,修改 AddController.java 中的输出信息为
再次运行 AddServiceApplication.java 中的 main 方法。 访问服务注册中心页面 http://localhost:8000 , 可以看到已经成功注册了两个 ADD-SERVICE-DEMO 服务,端口分别为 8100 和 8101 。
新建一个maven工程,修改pom.xml引入 spring cloud 依赖:
在 resources 目录中创建 application.yml 配置文件,在配置文件内容:
在 java 目录中创建一个包 demo ,在包中创建启动入口 RibbonClientApplication.java
这里配置了一个可以从服务注册中心读取服务列表,并且实现了负载均衡的 restTemplate 。
在demo包下新建一个子包controller,在controller子包下创建一个controller对外提供接口。
可以看到这里的请求url用了服务注册中心对应的 Application 。
运行 RibbonClientApplication.java 中的 main 方法,启动项目。 在浏览器中访问 http://localhost:8200/add?a=1&b=2 ,得到返回结果:
多次访问,查看 AddServiceApplication 的控制台,可以看到两个 ADD-SERVICE-DEMO 被负载均衡的调用。 demo源码 spring-cloud-1.0/ribbon-client-demo
新建一个maven工程,修改pom.xml引入 spring cloud 依赖:
在 resources 目录中创建 application.yml 配置文件,在配置文件内容:
在 java 目录中创建一个包 demo ,在包中创建启动入口 FeignClientApplication.java
在demo包下新建一个子包service,在service子包下创建一个接口 AddService.java 调用之前创建的微服务 ADD-SERVICE-DEMO 。
这里 @FeignClient 注解中的参数为服务注册中心对应的 Application 。
在demo包下再新建一个子包controller,在controller子包下创建一个 FeignController.java 对外提供接口。
FeignController 里注入了刚才创建的 AddService 接口。
运行 FeignClientApplication.java 中的 main 方法,启动项目。 在浏览器中访问 http://localhost:8300/add?a=1&b=2 ,得到返回结果:
多次访问,查看 AddServiceApplication 的控制台,可以看到两个 ADD-SERVICE-DEMO 被负载均衡的调用。 demo源码 spring-cloud-1.0/feign-client-demo
以 add-service-demo 为例, 复制 application.yml ,重命名为 application-docker.yml ,修改 defaultZone 为:
这里修改了 defaultZone 的访问url,如何修改取决于部署docker容器时的 –link 参数, –link 可以让两个容器之间互相通信。
修改 application.yml 中的 spring 节点为:
这里增加了 profiles 的配置,在maven打包时选择不同的profile,加载不同的配置文件。
在pom.xml文件中增加:
选择 docker profile,运行 mvn install -P docker ,打包项目并生成docker镜像, 注意docker-maven-plugin中的 <entryPoint> 标签里的内容不能换行,否则在生成docker镜像的时候会报错 。 运行成功后,登录docker节点,运行 docker images 应该可以看到刚才打包生成的镜像了。
在前一篇中,已经创建了一个 service-registry-demo 的docker镜像,这里先把这个镜像运行起来。
对这条命令做个简单说明, -d 指定当前容器运行在后台, –name 指定容器名称, –publish 指定端口映射到宿主机, –volume 这个挂载是为了解决容器内的时区和宿主机不一致的问题,让容器使用宿主机设置的时区,最后指定使用的docker镜像,镜像名称和标签需要根据自己的情况做修改。 运行这条命令之后, service-registry-demo 的容器就启动了。访问 http://宿主机IP:8000 ,打开注册中心的页面。 下边启动 add-service-demo 容器,
这条命令和上一条差不多,只是增加了一个 –link 参数, –link 指定容器间的连接,命令格式 –link 容器名:别名 ,这里连接了之前创建的名为 service-registry-demo 的容器,这里的别名和 application-docker.yml 文件中配置的 defaultZone 一致。其实就是通过别名找到了对应的容器IP,进到容器里查看 hosts 文件就明白了,其实就是加了条hosts映射。 add-service-demo 容器启动成功之后,刷新配置中心的页面,发现已经注册到配置中心了。