首页 > 其他分享 >微服务无感发布(二):微服务优雅的启动

微服务无感发布(二):微服务优雅的启动

时间:2024-10-11 22:22:48浏览次数:6  
标签:预热 服务 warmup 无感 优雅 HTTP 就绪 public

上一篇文章当中我们介绍了微服务在k8s环境下无感发布存在的问题和解决思路,今天来看一看代码的实现方式。

预热以及缓存加载

服务在容器启动之后,可能需要加载一些必要缓存,在这些缓存加载之后,才能够提供对外服务,注册到注册中心。在spring-cloud下,服务注册是通过监听WebServerInitializedEvent事件来触发的,所以只需要保证在该事件之前加载完缓存以及预热完成即可。

预热逻辑接口

首先,我们需要一个接口来定义预热方法:

/**
 * 预热 逻辑接口
 */
public interface BaseWarmupHandler {

    /**
     * 预热方法
     */
    void warmup();
}
http预热

接下来,我们实现一个预热HTTP请求的方法

@RestController
@RequestMapping
public class WarmupController {

    /**
     * 系统预热的接口
     * 参考项目: <link url="https://github.com/steinsag/warm-me-up"/>
     * @param request 请求参数
     * @return  返回
     */
    @PostMapping("/warmup")
    public Response<String> post(@RequestBody @Valid WarmupRequest request) {
        return Response.success(request.toString());
    }
}

在这个控制器中,我们定义了一个/warmup的POST接口,用于触发web容器相关预热逻辑。

预热逻辑实现
@Slf4j
@Service
public class ServletWarmupHandler implements BaseWarmupHandler{

    @Resource
    private Environment environment;

    @Resource
    private OkHttpClient okHttpClient;
    @Override
    public void warmup() {
        final String serverPort = environment.getProperty("local.server.port");
        final String baseUrl = "http://localhost:" + serverPort;
        final String warmUpEndpoint = baseUrl + "/warmup";

        log.debug("Sending REST request to warm up...");

        // 创建 MediaType
        MediaType mediaType = MediaType.get("application/json; charset=utf-8");
        // 创建 RequestBody
        RequestBody body = RequestBody.create(mediaType, JSON.toJSONString(createSampleMessage()));
        Request request = new Request.Builder()
                .url(warmUpEndpoint)
                .post(body)
                .build();

        try (Response response = okHttpClient.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                log.error("warm up request error:{}", response);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private WarmupRequest createSampleMessage() {
        final WarmupRequest warmUpRequestDto = new WarmupRequest();
        warmUpRequestDto.setInputMessage("warm me up");
        warmUpRequestDto.setPatternString("paretern");
        warmUpRequestDto.setSomeNumber(BigDecimal.TEN);
        warmUpRequestDto.setEm(WarmupEnum.ME);

        return warmUpRequestDto;
    }
}
启动时自动预热

最后,我们需要在服务启动时自动触发预热逻辑。这可以通过监听ApplicationReadyEvent事件来实现:

@Service
public class WarmupService implements ApplicationListener<ApplicationReadyEvent> {

    @Resource
    private ApplicationContext applicationContext;

    @Resource
    private ApplicationEventPublisher eventPublisher;

    @Override
    public void onApplicationEvent(@NonNull ApplicationReadyEvent event) {
        log.debug("warm up start .........");

        Map<String, BaseWarmupHandler> warmupHandlerMap = applicationContext.getBeansOfType(BaseWarmupHandler.class);
        for (Map.Entry<String, BaseWarmupHandler> entry : warmupHandlerMap.entrySet()) {
            try {
                entry.getValue().warmup();
            } catch (Exception e) {
                log.warn("warm up error, handler:{}, error:", entry.getKey(), e);
            }
        }

        log.debug("warm up done!");
        eventPublisher.publishEvent(new WarmupEndEvent(this));
    }
}

这个事例仅仅提供了一个预热web容器http请求的思路,在实际项目中要根据自身需求编写@Valid,jdbc或者缓存相关的预加载代码。

微服务就绪接口与Kubernetes就绪探针配置

在微服务架构中,每个服务的就绪时机可能各不相同,有的可能需要等待缓存加载完成,有的则需要确保已在注册中心成功注册。为了准确反映服务的就绪状态,项目应提供一个专门的就绪接口。以下是一个简单的Java接口示例:

@RestController("/lifeCycle")
public class StartedController implements ApplicationListener<InstanceRegisteredEvent<?>> {
    
    /** 项目是否启动完成 */
    private boolean started = false;
    
    @GetMapping("/started")
    public boolean started() {
        if (started) {
            return true;
        }
        // 这里根据项目定义的异常类型返回
        throw new RuntimeException("服务尚未启动");
    }

    @Override
    public void onApplicationEvent(InstanceRegisteredEvent<?> event) {
        // InstanceRegisteredEvent 是spring-cloud 提供的注册中心模版完成注册时发送的事件。
        // 这个里可以根据项目调整项目成功的时机
        this.started = true;
    }
}

在Kubernetes环境中,就绪探针(Readiness Probe)用于判断服务是否已经准备好接收流量。以下是一个Kubernetes容器配置就绪探针的示例:

readinessProbe:
  httpGet:
      # host:连接使用的主机名,默认是 Pod 的 IP。也可以在 HTTP 头中设置 "Host" 来代替。
      # scheme:用于设置连接主机的方式(HTTP 还是 HTTPS)。默认是 "HTTP"。
      # path:访问 HTTP 服务的路径。默认值为 "/"。
      path: /lifeCycle/started
      # httpHeaders:请求中自定义的 HTTP 头。HTTP 头字段允许重复。
      httpHeaders:
        - name: Accept
          value: application/json
      # port:访问容器的端口号或者端口名。如果数字必须在 1~65535 之间。
      port: 10087
  initialDelaySeconds: 5
  # 执行探测的时间间隔(单位是秒)。默认是 10 秒。最小值是 1。 当容器未就绪时,ReadinessProbe 可能会在除配置的
  periodSeconds: 5

提示:就绪探针通过HTTP请求访问指定的路径和端口,如果接口返回的状态码大于或等于200且小于400,则表示探测成功,服务已就绪;否则,表示探测失败,服务尚未就绪。

引用

shelltea.warmup-spring-boot-starter
kubernetes文档

标签:预热,服务,warmup,无感,优雅,HTTP,就绪,public
From: https://www.cnblogs.com/haohaoxiangshou/p/18458816

相关文章

  • 纯干货无广告,毕业大论文,如何优雅地拼拼凑凑,降重和润色
    目录拼拼凑凑风格选定实例(使用GPT翻译成中文)拼拼凑凑(手动拼凑)拼拼凑凑(GPT直述)知网查重率AIGC检测率查重普通查重AIGC检测降重直接使用GPT先缩写后扩写缩写扩写中日英互译中翻日日翻英英翻中效果润色(必须得进行)GPT润色人工润色(推荐)拼拼凑凑风格选定风格1风格2风格3实例(使......
  • python+flask计算机毕业设计中小学家校服务系统设计与实现(程序+开题+论文)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景在当今教育体系中,家校合作已成为促进学生全面发展不可或缺的一环。随着信息技术的迅猛发展,传统的家校沟通方式已难以满足日益增长的信息交......
  • Nacos服务注册与发现原理
    Nacos是什么?Nacos是阿里巴巴开源的一种微服务组件,它主要用于解决分布式系统中多服务实例的动态变化问题,并提供了一种集中、统一的方式来管理配置文件。此外,Nacos还提供了可视化的界面,使得服务实例的管理和配置文件的监控变得更加直观和方便。Nacos的原理在微服务远程调用的过......
  • Nacos服务注册与发现的原理
    注册中心原理在微服务的远程调用中,包括两个角色:服务提供者:提供接口供其他微服务访问。服务消费者:调用其他微服务提供的接口。在大型的微服务项目中,微服务提供者的数量非常多,为了管理这些服务就引入了注册中心的概念。注册中心,服务提供者,服务消费者三者之间的关系如下:流程......
  • Nacos服务注册与发现的原理
    服务注册和发现1.注册中心原理在微服务远程调用的过程中,包括两个角色:●服务提供者:提供接口供其它微服务访问,比如item-service●服务消费者:调用其它微服务提供的接口,比如cart-service在大型微服务项目中,服务提供者的数量会非常多,为了管理这些服务就引入了注册中心的概念。......
  • Nacos服务注册与发现的原理和如何配置
    由于在大型为微服务项目中存在很多服务提供者,甚至相同的服务会使用不同的路径去调用,为了更好的管理并调用这些服务,我们需要使用注册中心来帮助我们管理这些服务以nacos为例,1.当使用nacos来管理服务的时候,服务启动时会将自己的注册信息,例如服务名,Ip,端口注册到注册中心中。2.调......
  • Nacos服务注册与发现
    1.基本原理概述在微服务调用过程中主要是两个角色一个是服务的消费者,一个是服务的提供者服务提供者:提供接口供其它微服务访问服务消费者:调用其它微服务提供的接口大型微服务项目中,服务提供者的数量会非常多,为了管理这些服务,就需要注册中心来对这些服务进行一个统一管理,服......
  • 配置和管理samba服务器
    samba服务建起了Linux和Windows之间的桥梁,实现了不同系统之间的互通,如复制文件、实现不同操作系统的资源共享。在实际应用中,可以将samba服务器架设成一个强大的文件服务器。在本篇文章中,将实现Linux和Linux之间、Linux和Windows之间的samba服务。地址规划OSIPrehl9.0192.168.96.171......
  • Nacos服务相关
    nacos是阿里开源的一款用于微服务的多服务管理工具,通过服务注册进入内部服务器可以看到注册的服务;服务注册原理:在微服务远程调用的过程中,包括两个角色:服务调用者,调用其他服务的接口,服务提供者,提供接口给其他服务调用在大型微服务项目中,服务提供者的数量会非常多,为了管理这些服......
  • 65websocket服务端和客户端实现
     #server.pyimportasyncioimportwebsocketsasyncdefecho(websocket,path):asyncformessageinwebsocket:print(f"serverReceived:{message}")awaitwebsocket.send(f"Serverresponse:{message}")start_serve......