2 Star 1 Fork 0

zhrun8899 / learning-notes

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
springcloud and springboot.md 31.60 KB
一键复制 编辑 原始数据 按行查看 历史
zhrun8899 提交于 2018-12-17 08:13 . 2018121

微服务的经验和建议

1、建议尽量不要使用Jsp,

页面开发推荐使用Thymeleaf。

2. Web项目建议独立部署Tomcat,

不要使用内嵌的Tomcat,内嵌Tomcat部署Jsp项目会偶现龟速访问的情况。

3、不要为了追求技术而追求技术,

确定进行微服务架构改造之前,需要考虑以下几方面的因素: 1)团队的技术人员是否已经具备相关技术基础。 2)公司业务是否适合进行微服务化改造,并不是所有的平台都适合进行微服务化改造,比如:传统行业有很多复杂垂直的业务系统。 3)Spring Cloud生态的技术有很多,并不是每一种技术方案都需要用上,适合自己的才是最好的。

微服务给数据库带来的挑战

每个微服务都有自己独立的数据库,那么后台管理的联合查询怎么处理?这应该是大家会普遍遇到的一个问题,有三种处理方案。

1)严格按照微服务的划分来做

微服务相互独立,各微服务数据库也独立,后台需要展示数据时,调用各微服务的接口来获取对应的数据,再进行数据处理后展示出来,这是标准的用法,也是最麻烦的用法。

2) 将业务高度相关的表放到一个库中

将业务关系不是很紧密的表严格按照微服务模式来拆分,这样既可以使用微服务,也避免了数据库分散导致后台系统统计功能难以实现,是一个折中的方案。

3)数据库严格按照微服务的要求来切分

以满足业务高并发,实时或者准实时将各微服务数据库数据同步到NoSQL数据库中,在同步的过程中进行数据清洗,用来满足后台业务系统的使用,推荐使用MongoDB、HBase等。

4) 结论

第一种方案适合业务较为简单的小公司;

第二种方案,适合在原有系统之上,慢慢演化为微服务架构的公司;

第三种适合大型高并发的互联网公司。

jenkins

待补充

session共享

session共享有很多种方式,比如使用tomcat sesion共享机制,但我比较推荐使用redis缓存来做session共享。

RestTemplate使用

1.直接声明,只能访问URL

@Bean ​ RestTemplate restTemplate() { ​ return new RestTemplate(); ​ }

直接访问URL,

String url = "http://localhost:9002/dc";

 return restTemplate.getForObject(url, String.class); 

使用 LoadBalancerClient loadBalancerClient 取出某服务地址,然后访问

 @Autowired
 LoadBalancerClient loadBalancerClient;
 ServiceInstance serviceInstance = loadBalancerClient.choose("SMS-SERVICE");
​        String url = "http://" + serviceInstance.getHost() + ":" + serviceInstance.getPort() + "/dc";
​        return restTemplate.getForObject(url, String.class);

这种方法无法直接访问eureka中注册的service名称

下面这种访问会出错: String url = "http://SMS-SERVICE/dc"; return restTemplate.getForObject(url, String.class);

2.与@loadBalced 配合使用,即与ribbon配合使用

@Bean
​    @LoadBalanced
​    RestTemplate restTemplate() {
​        return new RestTemplate();
​    } 

这种声明只能访问 eureka中注册的service名称 ,如 String url = "http://SMS-SERVICE/dc"; return restTemplate.getForObject(url, String.class); 其它访问URL的则会出错,即第一步是从eureka中找出访问地址,再访问.

springcloud Finchley:

builds and works with Spring Boot 2.0.x, and is not expected to work with Spring Boot 1.5.x.

***springcloud Dalston and Edgware release trains

build on Spring Boot 1.5.x, and are not expected to work with Spring Boot 2.0.x.

springboot2:

springboot2.1.0

springboot1.5:

  • statble:1.5.17
  • snashot:1.5.18

1.服务治理

  • dubbo dubbox

  • Netflix的Eureka:可以选择

  • etcd

  • zookeeper

  • Apache的Consul

    可以排除,刷新困难 `运行: consul agent -dev -ui -node=cy consul agent -dev -http-port 8080 +**解决consul在其它机器无法访问的问题: consul agent -dev -client 0.0.0.0 **

` /etc/consul.d目录下合建base-config.json:

{
​ "ports": {
​ "http": 8080 ​ }
}

命令行:consul node:节点名 Address:节点地址 Status:alive表示节点健康 Type:server运行状态是server状态 DC:dc1表示该节点属于DataCenter1 eureka 1x开源,2x要闭源了.可以选择consul. 建议大框架使用kubernetes. consul agent常用命令解读 -data-dir 作用:指定agent储存状态的数据目录,这是所有agent都必须的,对server尤其重要,因为他们必须持久化集群的状态

-config-dir 作用:指定service的配置文件和检查定义所在的位置。目录必需为consul.d,文件内容都是json格式的数据。配置详解见官方

-config-file 作用:指定一个要装载的配置文件

-dev 作用:开发服务器模式,虽然是server模式,但不用于生产环境,因为不会有任何持久化操作,即不会有任何数据写入到磁盘

-bootstrap-expect 作用: 参数表明该服务运行时最低开始进行选举的节点数,当设置为1时,则意味允许节点为一个时也进行选举;当设置为3时,则等到3台节点同时运行consul并加入到server才能参与选举,选举完集群才能够正常工作。 一般建议服务器结点3-5个。

-node 作用:指定节点在集群中的名称,该名称在集群中必须是唯一的(默认这是机器的主机名),直接采用机器的IP

-bind 作用:指明节点的IP地址,一般是0.0.0.0或者云服务器内网地址,不能写阿里云外网地址。这是Consul侦听的地址,它必须可以被集群中的所有其他节点访问。虽然绑定地址不是绝对必要的,但最好提供一个。

-server 作用:指定节点为server,每个数据中心(DC)的server数推荐3-5个。

-client 作用:指定节点为client,指定客户端接口的绑定地址,包括:HTTP、DNS、RPC 默认是127.0.0.1,只允许回环接口访问

10.-datacenter 作用:指定机器加入到哪一个数据中心中。老版本叫-dc,-dc已经失效

2、分布式配置管理

  • 百度的Disconf
  • 360的QConf
  • 淘宝的Diamond:过于简陋
  • spring cloud config: 是静态的,得配合Spring Cloud Bus实现动态的配置更新。
  • 当当的apollo

说明: spring cloud config 中配置的自动刷新还是有点问题: 要实现这个功能,必须使用rabbitmq,acuator,修改配置后还需要向client/refresh发送一个post请求,才能刷新配置,比较麻烦. 另一个方式是git配置hook,维护实现上比较麻烦.

建议使用apollo.

spring config

访问地址:

  • /{application}/{profile}[/{label}]
  • /{application}-{profile}.yml
  • /{label}/{application}-{profile}.yml
  • /{application}-{profile}.properties
  • /{label}/{application}-{profile}.properties

说明 :

profile:dev,default,test,pro等

label:git分支,如 master,dev等,一般使用master即可.

/{application}/{profile}[/{label}]

http://localhost:1101/config-client/dev/master

http://localhost:1101/config-client/defaut/master

/{application}-{profile}.yml(properties)

http://localhost:1101/config-client-dev.yml

http://localhost:1101/config-client-dev.properties

注意:无论git仓库中存放的是properties还是yml都可以通过两种方式访问.

/{label}/{application}-{profile}.yml(properties)

http://localhost:1101/master/config-client-dev.yml

http://localhost:1101/master/config-client-default.yml

注意:如果指定的profile不存在,则返回default

apollo 使用

namespace (命名空间)

  • 一个应用下不同配置的分组,可以简单地把namespace类比为文件,不同类型的配置存放在不同的文件中,如数据库配置文件,RPC配置文件,应用自身的配置文件等

overall-architecture

Admin Service

  • 提供配置管理接口
  • 提供配置修改、发布等接口
  • 接口服务对象为Portal

Meta Server

  • Portal通过域名访问Meta Server获取Admin Service服务列表(IP+Port)
  • Client通过域名访问Meta Server获取Config Service服务列表(IP+Port)
  • Meta Server从Eureka获取Config Service和Admin Service的服务信息,相当于是一个Eureka Client
  • 增设一个Meta Server的角色主要是为了封装服务发现的细节,对Portal和Client而言,永远通过一个Http接口获取Admin Service和Config Service的服务信息,而不需要关心背后实际的服务注册和发现组件
  • Meta Server只是一个逻辑角色,在部署时和Config Service是在一个JVM进程中的,所以IP、端口和Config Service一致

Eureka

  • 基于EurekaSpring Cloud Netflix提供服务注册和发现
  • Config Service和Admin Service会向Eureka注册服务,并保持心跳
  • 为了简单起见,目前Eureka在部署时和Config Service是在一个JVM进程中的(通过Spring Cloud Netflix)

Portal

  • 提供Web界面供用户管理配置
  • 通过Meta Server获取Admin Service服务列表(IP+Port),通过IP+Port访问服务
  • 在Portal侧做load balance、错误重试

Client

  • Apollo提供的客户端程序,为应用提供配置获取、实时更新等功能
  • 通过Meta Server获取Config Service服务列表(IP+Port),通过IP+Port访问服务
  • 在Client侧做load balance、错误重试

单机版:

下载: https://github.com/nobodyiam/apollo-build-scripts

mysql数据库,两个,ApolloPortalDBApolloConfigDB

修改配置:demo.sh

启动服务:demo.sh start

启动测试:demo.sh client

端口:

  • 8080,自带的eureaka服务,与apollo-configservice 组合在一起,meta service和config service是部署在同一个JVM进程
  • 8070:管理页面
  • 8090:服务提供端口

分布式:

1.下载

  • apollo-configservice-x.x.x-github.zip
  • apollo-adminservice-x.x.x-github.zip
  • apollo-portal-x.x.x-github.zip

2.数据库配置

3.配置apollo-portal的meta service信息

4.部署Apollo服务端

运行各服务的statup.sh,关闭则shutdown.sh

serverport在sh文件中配置

1.4 springboot 使用apolloconfig

1.本地开发模式

修改/opt/settings/server.properties(Mac/Linux)或C:\opt\settings\server.properties(Windows)文件,设置env为Local:

env=Local

本地配置目录位于:

  • Mac/Linux: /opt/data/{appId}/config-cache

  • Windows: C:\opt\data{appId}\config-cache

    在本地开发模式下,Apollo不会实时监测文件内容是否有变化,所以如果修改了配置,需要重启应用生效。

2.测试模式

引入pom依赖

<dependency>
    <groupId>com.ctrip.framework.apollo</groupId>
    <artifactId>apollo-mockserver</artifactId>
    <version>1.1.0</version>
</dependency>

*在test的resources下放置mock的数据

文件名格式约定为mockdata-{namespace}.properties

3.批量任务框架 Spring Cloud Task

  • (1)Spring Cloud组件中的Task

  • (2)LTS

4.客户端负载均衡

  • Ribbon
  • Feign:声明式服务调用,本质上就是Ribbon+Hystrix ,方便我们程序员些更优美的代码的。 建议使用feign

5.hystrix

img

Hystrix:客户端容错保护,特性有服务降级、服务熔断、请求缓存、请求合并、依赖隔离。

断路器增加了稳定性和灵活性,以一个系统,提供稳定性,而系统从故障中恢复,并尽量减少此故障的对性能的影响。它可以帮助快速地拒绝对一个操作,即很可能失败,而不是等待操作超时(或者不返回)的请求,以保持系统的响应时间。如果断路器提高每次改变状态的时间的事件,该信息可以被用来监测由断路器保护系统的部件的健康状况,或以提醒管理员当断路器跳闸,以在打开状态。

Hystrix Dashboard:监控显示 仪表盘,监控集群模式和单点模式,其中集群模式需要收集器Turbine配合

Turbine: 是集群收集器,服务于Dashboard的。

ribbon+hystrix

@HystrixCommand(fallbackMethod = "fallback")
        public String consumer() {
            return restTemplate.getForObject("http://eureka-client/dc", String.class);
        }

        public String fallback() {
            return "fallback";
        }

注意 :fallBackMetho中的形参必须与主函数一致

feign+hystrix

@FeignClient(value = "MICROSERVICECLOUD-DEPT",fallbackFactory=DeptClientServiceFallbackFactory.class)
public interface DeptClientService
{
	@RequestMapping(value = "/dept/get/{id}", method = RequestMethod.GET)
	public Dept get(@PathVariable("id") long id);

@RequestMapping(value = "/dept/list", method = RequestMethod.GET)
	public List<Dept> list();
	
	@RequestMapping(value = "/dept/add", method = RequestMethod.POST)
	public boolean add(Dept dept);
}

DeptClientServiceFallbackFactory 代码:

@Component // 不要忘记添加,不要忘记添加
public class DeptClientServiceFallbackFactory implements FallbackFactory<DeptClientService>
{
	@Override
	public DeptClientService create(Throwable throwable)
	{
		return new DeptClientService() {
			@Override
			public Dept get(long id)
			{
				return new Dept().setDeptno(id).setDname("该ID:" + id + "没有没有对应的信息,Consumer客户端提供的降级信息,此刻服务Provider已经关闭")
						.setDb_source("no this database in MySQL");
			}

			@Override
			public List<Dept> list()
			{
				return null;
			}

			@Override
			public boolean add(Dept dept)
			{
				return false;
			}
		};
	}
}

6.网关

文章:http://www.ityouknow.com/springcloud/2018/01/20/spring-cloud-zuul.html

Spring Cloud Zuul: API服务网关,功能有路由分发和过滤。

如果只是请求转发,zuul的性能不一定比nginx低,但是如果涉及到静态资源,还是建议在前端使用nginx做一下代理。

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

  • Authentication

  • Insights

  • Stress Testing

  • Canary Testing:

  • Dynamic Routing:动态路由

  • Service Migration:服务迁移

  • Load Shedding:减载荷

  • Security安全

  • Static Response handling

  • Active/Active traffic management

    网关是最后与用户交互的页面,访问地址:http://localhost:9001/sms-service-consumer/dcs

    其中是sms-service-consumer 是consumer在eureka注册的服务,dcs是具体的访问地址,通过要eureka取得该服务的具体地址,可以实现用户的访问 .同时在这个层面还可以加上各种filter及权限控制及核验逻辑,服务聚合,统一的异常处理 ,等;同时使得相应的服务提供者更加纯粹.

    路由重试

    添加Spring Retry依赖

    首先在spring-cloud-zuul项目中添加Spring Retry依赖。

    <dependency>
    	<groupId>org.springframework.retry</groupId>
    	<artifactId>spring-retry</artifactId>
    </dependency>

    再配置文件中配置启用Zuul Retry

    #是否开启重试功能
    zuul.retryable=true
    #对当前服务的重试次数
    ribbon.MaxAutoRetries=2
    #切换相同Server的次数
    ribbon.MaxAutoRetriesNextServer=0

自定义Filter示例

我们假设有这样一个场景,因为服务网关应对的是外部的所有请求,为了避免产生安全隐患,我们需要对请求做一定的限制,比如请求中含有Token便让请求继续往下走,如果请求不带Token就直接返回并给出提示。

首先自定义一个Filter,在run()方法中验证参数是否含有Token。

public class TokenFilter extends ZuulFilter {

    private final Logger logger = LoggerFactory.getLogger(TokenFilter.class);

    @Override
    public String filterType() {
        return "pre"; // 可以在请求被路由之前调用
    }

    @Override
    public int filterOrder() {
        return 0; // filter执行顺序,通过数字指定 ,优先级为0,数字越大,优先级越低
    }

    @Override
    public boolean shouldFilter() {
        return true;// 是否执行该过滤器,此处为true,说明需要过滤
    }

    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();

        logger.info("--->>> TokenFilter {},{}", request.getMethod(), request.getRequestURL().toString());

        String token = request.getParameter("token");// 获取请求的参数

        if (StringUtils.isNotBlank(token)) {
            ctx.setSendZuulResponse(true); //对请求进行路由
            ctx.setResponseStatusCode(200);
            ctx.set("isSuccess", true);
            return null;
        } else {
            ctx.setSendZuulResponse(false); //不对其进行路由
            ctx.setResponseStatusCode(400);
            ctx.setResponseBody("token is empty");
            ctx.set("isSuccess", false);
            return null;
        }
    }

}

将TokenFilter加入到请求拦截队列,在启动类中添加以下代码:

@Bean
public TokenFilter tokenFilter() {
	return new TokenFilter();
}

这样就将我们自定义好的Filter加入到了请求拦截中。

路由熔断

当我们的后端服务出现异常的时候,我们不希望将异常抛出给最外层,期望服务可以自动进行一降级。Zuul给我们提供了这样的支持。当某个服务出现异常时,直接返回我们预设的信息。

我们通过自定义的fallback方法,并且将其指定给某个route来实现该route访问出问题的熔断处理。主要继承ZuulFallbackProvider接口来实现,ZuulFallbackProvider默认有两个方法,一个用来指明熔断拦截哪个服务,一个定制返回内容。

public interface ZuulFallbackProvider {
   /**
	 * The route this fallback will be used for.
	 * @return The route the fallback will be used for.
	 */
	public String getRoute();

	/**
	 * Provides a fallback response.
	 * @return The fallback response.
	 */
	public ClientHttpResponse fallbackResponse();
}

实现类通过实现getRoute方法,告诉Zuul它是负责哪个route定义的熔断。而fallbackResponse方法则是告诉 Zuul 断路出现时,它会提供一个什么返回值来处理请求。

后来Spring又扩展了此类,丰富了返回方式,在返回的内容中添加了异常信息,因此最新版本建议直接继承类FallbackProvider

我们以上面的spring-cloud-producer服务为例,定制它的熔断返回内容。

@Component
public class ProducerFallback implements FallbackProvider {
    private final Logger logger = LoggerFactory.getLogger(FallbackProvider.class);

    //指定要处理的 service。
    @Override
    public String getRoute() {
        return "spring-cloud-producer";
    }

    public ClientHttpResponse fallbackResponse() {
        return new ClientHttpResponse() {
            @Override
            public HttpStatus getStatusCode() throws IOException {
                return HttpStatus.OK;
            }

            @Override
            public int getRawStatusCode() throws IOException {
                return 200;
            }

            @Override
            public String getStatusText() throws IOException {
                return "OK";
            }

            @Override
            public void close() {

            }

            @Override
            public InputStream getBody() throws IOException {
                return new ByteArrayInputStream("The service is unavailable.".getBytes());
            }

            @Override
            public HttpHeaders getHeaders() {
                HttpHeaders headers = new HttpHeaders();
                headers.setContentType(MediaType.APPLICATION_JSON);
                return headers;
            }
        };
    }

    @Override
    public ClientHttpResponse fallbackResponse(Throwable cause) {
        if (cause != null && cause.getCause() != null) {
            String reason = cause.getCause().getMessage();
            logger.info("Excption {}",reason);
        }
        return fallbackResponse();
    }
}

当服务出现异常时,打印相关异常信息,并返回”The service is unavailable.”。

7.系统总线

RabbitMQ

Kafka

Spring Cloud Bus : config修改完配置后各个结点都要refresh才能生效实在太麻烦,所以交给bus来通知服务节点刷新配置的。 一种最简单的方式重新一下Config Client进行重新获取,但Spring Cloud绝对不会让你这样做的,Spring Cloud Bus正是提供一种操作使得我们在不关闭服务的情况下更新我们的配置。

消费使用amqpRestTemplate非常方便.

8.Stream

8.1 与 springcloud bus关系?

简化研发人员对MQ使用的复杂度,弱化MQ的差异性,达到程序和MQ松耦合。 消息驱动,有Sink、Source、Processor三种通道,特性有订阅发布、消费组、消息分区。 目前为止Spring Cloud Stream只支持下面两个著名的消息中间件的自动化配置:

  • RabbitMQ
  • Kafka

rabbitmq 启动:service rabbitmq-server start

topic设置:

spring.cloud.stream.bindings.input.destination=sms

普通设置

spring.rabbitmq.host=192.168.0.37 spring.rabbitmq.port=5672 spring.rabbitmq.username=guest spring.rabbitmq.password=guest

消费组:消息生产者发送消息给某个具体微服务时,只希望被消费一次,同时负载均衡

spring.cloud.stream.bindings.input.group:只会有一个消费者会收到消息 当我们没有为应用指定消费组的时候,Spring Cloud Stream会为其分配一个独立的匿名消费组。所以,如果同一主题下所有的应用都没有指定消费组的时候,当有消息被发布之后,所有的应用都会对其进行消费,因为它们各自都属于一个独立的组中。大部分情况下,我们在创建Spring Cloud Stream应用的时候,建议最好为其指定一个消费组,以防止对消息的重复处理,除非该行为需要这样做(比如:刷新所有实例的配置等)

spring.cloud.stream.bindings.example-topic.group=aaa

消息分区

当生产者将消息数据发送给多个消费者实例时,保证拥有共同特征的消息数据始终是由同一个消费者实例接收和处理。 spring.cloud.stream.bindings.input.consumer.partitioned: 通过该参数开启消费者分区功能;

spring.cloud.stream.instanceCount: 该参数指定了当前消费者的总实例数量;

spring.cloud.stream.instanceIndex: 该参数设置当前实例的索引号,从0开始,最大值为spring.cloud.stream.instanceCount参数 - 1。我们试验的时候需要启动多个实例,可以通过运行参数来为不同实例设置不同的索引值。 spring.cloud.stream.bindings.output.destination=greetings spring.cloud.stream.bindings.output.producer.partitionKeyExpression=payload spring.cloud.stream.bindings.output.producer.partitionCount=2

9.sleuth

http://blog.csdn.net/forezp/article/details/70162074 Spring Cloud Sleuth 主要功能就是在分布式系统中提供追踪解决方案,并且兼容支持了 zipkin. 分布式服务追踪,需要搞清楚TraceID和SpanID以及抽样,如何与ELK整合。 单次请求在微服务节点中跳转无法追溯,解决任务链日志追踪问题的。

Spring Cloud Sleuth是对Zipkin的一个封装,对于Span、Trace等信息的生成、接入HTTP Request,以及向Zipkin Server发送采集信息等全部自动完成。

10 Zipkin

http://blog.didispace.com/spring-cloud-starter-dalston-8-4/ https://blog.csdn.net/forezp/article/details/70162074 在实际的应用场景中,Zipkin可以结合压力测试工具一起使用,分析系统在大压力下的可用性和性能。

从jar包和包名来看它不属于Spring Cloud的一员,但是它与Spring Cloud Sleuth的抽样日志结合的天衣无缝。乍一看它与Hystrix的Dashboard作用有重叠的部分,但是他们的侧重点完全不同。Dashboard侧重的是单个服务的统计和是否可用,Zipkin侧重的监控环节时长。简言之,Dashboard侧重故障诊断,Ziokin侧重性能优化。

针对服务化应用全链路追踪的问题,Google发表了Dapper论文,介绍了他们如何进行服务追踪分析。其基本思路是在服务调用的请求和响应中加入ID,标明上下游请求的关系。利用这些信息,可以可视化地分析服务调用链路和服务间的依赖关系.

对应Dpper的开源实现是Zipkin,支持多种语言包括JavaScript,Python,Java, Scala, Ruby, C#, Go等。

应用实现: 1.建立一个server,引用zipken-server 2.建立客户端,引入 sleuth-zipken,同时在配置中填写zipken-server中的地址 3.还可以用消息中间件实现消息收集 引入 spring-cloud-sleuth-stream 及 spring-cloud-starter-stream-rabbit 配置中增加rabbitmq的配置

Zipkin提供了可插拔数据存储方式:In-Memory、MySql、Cassandra以及Elasticsearch。接下来的测试为方便直接采用In-Memory方式进行存储,生产推荐Elasticsearch。

11.springboot admin

注意:dalson.release不支持admin server,会报错;需要使用edgeware.release.

12. Spring Cloud Security

13 Spring Cloud Data Flow

一个云本地程序和操作模型,组成数据微服务在一个结构化的平台上。

上线策略

蓝绿发布:

新版本上线,然后把流量导过来,旧系统下线.只有一个版本有流量,另一个没有流量。

主要思路是在新版本在另外一套独立的资源上上线,新版本起来后将所有的流量从老版本切到新版本上来。当新版本工作正常,则删除老版本;当新版本工作有问题,则快速能切回到老版本。因此蓝绿发布看上是一种热部署的方式,目的是减少发布过程中的服务停止时间。

ABTest:

两个版本同时在线,观察哪个版本用户理欢迎.强调的是评估两个版本的被访问情况,评估版本的受欢迎程度,然后决策保留哪一个。

金丝雀测试:

向新版本导入一部分流量,观察新版本各种表现.上线一个新版本使用实际流程测bug,稳定性、实际环境测匹配度等,类似gamma的测试。就像用金丝雀去一样,把一个新版本拿到实际环境去验证下,然后看是否能满足要求

SpringCloud 与kubernetes 比较:

微服务 | Spring Cloud 和 Kubernetes 哪个更好?

微服务要求或特点: 集成,扩展性,高可用,自愈

Spring Cloud 可以用来创建一个简单的基于微服务的系统的综合视角。为了构建一个能扩展到数千个服务的可扩展且有弹性的微服务系统,它就必须有一套拥有广泛的构建时和运行时能力的工具集来帮助管理和控制。使用 Spring Cloud,既能实现功能型服务(比如统计服务,账号服务以及通知服务),又能实现基础架构服务(比如日志分析,配置服务器,服务发现,认证服务等)。 单独使用 Spring Cloud 在微服务旅程上无法走得很长远,在一个完整的微服务经历中,开发者还需要考虑自动化部署,调度,资源管理,进程隔离,自愈,构建流水线等功能。在这点上,我觉得单独拿 Spring Cloud 和 Kubernetes 来比较不太公平,更公正的比较应该是 Spring Cloud + Cloud Foundry(或者 Docker Swarm)和 Kubernetes 来比较。但是那也说明,对一个完整的端到端的微服务经历,Spring Cloud 还需要补充一个应用平台,就像 Kubernetes 那样。 Kubernetes 是兼容多种语言的,因此它的服务和原语是通用的,不像 Spring Cloud 对 JVM 那样,没有针对不同的平台做优化。例如,配置是通过环境变量或者挂载文件系统传递给应用的。它没有 Spring Cloud 配置提供的那样精妙的配置更新能力。

Kubernetes 不是一个针对开发者的平台。它的目的是供有 DevOps 思想的IT人员使用。因此,Java 开发者需要学习一些新的概念,并更开放得学习新的解决问题的方式。不管使用 MiniKube 来部署一个 Kubernetes 开发实例是多么得容易,手工安装一个高可用的 Kubernetes 集群是有明显的操作成本的。

Kubernetes 仍是一个相对较新的平台(2年),它也还在活跃得开发和生长中。因此每个版本都会有许多新的特性,使得我们很难去一直跟踪。好消息是这个问题已经被正视,API 做成了可扩展且是后向兼容的。

使用随机端口

为方便程序运行多份,可以设置端口为0,这样程序可运行多个实例 server.port=0 但这样会在服务管理上看到的是同一个实例名,可以手工设置系统实例ID: eureka.instance.instance-id=${spring.application.name}:${random.int}

api网关

## 私有云开源解决方案如下:

Kong kong是基于Nginx+Lua进行二次开发的方案, https://konghq.com/ Netflix Zuul,zuul是spring cloud的一个推荐组件,https://github.com/Netflix/zuul orange,这个开源程序是国人开发的,http://orange.sumory.com/

公有云解决方案:

Amazon API Gateway,https://aws.amazon.com/cn/api-gateway/ 阿里云API网关,https://www.aliyun.com/product/apigateway/ 腾讯云API网关, https://cloud.tencent.com/product/apigateway

自开发解决方案:

基于Nginx+Lua+ OpenResty的方案,可以看到Kong,orange都是基于这个方案 基于Netty、非阻塞IO模型。 通过网上搜索可以看到国内的宜人贷等一些公司是基于这种方案,是一种成熟的方案。 基于Node.js的方案。 这种方案是应用了Node.js天生的非阻塞的特性。 基于java Servlet的方案。 zuul基于的就是这种方案,这种方案的效率不高,这也是zuul总是被诟病的原因。

企业怎么选择API网关

1.性能与可用性

  • 从性能上来说,需要让网关增加的时间消耗越短越好,个人觉得需要10ms以下。 系统需要采用非阻塞的IO,如epoll,NIO等。网关和各种依赖的交互也需要是非阻塞的,这样才能保证整体系统的高可用性,如:Node.js的响应式编程和基于java体现的RxJava和Future。
  • 网关必须支持集群部署,任务一台服务器的crash都应该不影响整体系统的可用性。
  • 多套网关应该支持同一管理平台和同一监控中心。如: 一个企业的OpenAPI网关和内部应用的多个系统群的不同的微服务网关可以在同一监控中心进行监控。

2.可扩展性、可维护性

一款产品总有不能满足生产需求的地方,因此需求思考产品在如何进行二次开发和维护,是否方便公司团队接手维护产品。

3.需求匹配度

需要评估各API网关在需求上是否能满足,如: 如果是OpenAPI平台需要使用API网关,那么需要看API网关在合作伙伴应用接入、合作伙伴门户集成、访问次数限额等OpenAPI核心需求上去思考产品是否能满足要求。如果是微服务网关,那么要从微服务的运维、监控、管理等方面去思考产品是否足够强大。

4.是否开源?公司是否有自开发的能力?

kong是基于ngnix+lua的,从公司的角度比较难于找到能去维护这种架构产品的人。 需求评估当前公司是否有这个能力去维护这个产品。 zuul因为架构的原因在高并发的情况下性能不高,同时需要去基于研究整合开源的适配zuul的监控和管理系统。 orange由于没有被大量使用,同时是国内个人在开源,在可持续性和社区资源上不够丰富,出了问题后可能不容易找到人问。

1
https://gitee.com/zhrun8899/learning-notes.git
git@gitee.com:zhrun8899/learning-notes.git
zhrun8899
learning-notes
learning-notes
master

搜索帮助