当前位置: 首页 > news >正文

珠海市住房和城乡建设厅网站华为认证网络工程师怎么考

珠海市住房和城乡建设厅网站,华为认证网络工程师怎么考,c2c模式的企业,网站开发保密合同范本重新启动企业应用程序时#xff0c;客户打开Web浏览器时会看到什么#xff1f; 他们什么也没看到#xff0c;服务器还没有响应#xff0c;因此Web浏览器显示ERR_CONNECTION_REFUSED 应用程序前面的Web代理#xff08;如果有#xff09;注意到它已关闭并显示“友好”错误… 重新启动企业应用程序时客户打开Web浏览器时会看到什么 他们什么也没看到服务器还没有响应因此Web浏览器显示ERR_CONNECTION_REFUSED 应用程序前面的Web代理如果有注意到它已关闭并显示“友好”错误消息 该网站需要永久加载-它接受了套接字连接和HTTP请求但是等待响应直到应用程序实际启动 您的应用程序进行了横向扩展以便其他节点可以快速处理请求而不会发出通知并且会话始终得以复制 …或应用程序启动速度如此之快以至于没有人注意到任何中断嘿普通的Spring Boot Hello world应用程序从点击java -jar ... [Enter]开始服务请求不到3秒。 顺便说一句请检出SPR-8767启动过程中的并行bean初始化 。 处于情况4和5.绝对更好。但是在本文中我们将介绍对情况1和3的更强大的处理。 典型的Spring Boot应用程序会在所有Bean都加载完毕时状态1在最后启动Web容器例如Tomcat。这是一个非常合理的默认值因为它会阻止客户端在完全配置之前无法访问我们的端点。 但是这意味着我们无法区分启动了几秒钟的应用程序和关闭了的应用程序。 因此想法是要有一个应用程序在加载时显示一些有意义的启动页面类似于显示“ 服务不可用 ”的Web代理。 但是由于此类启动页面是我们应用程序的一部分因此它可能会更深入地了解启动进度。 我们希望在初始化生命周期中更早地启动Tomcat但是要提供特殊目的的启动页面直到Spring完全引导为止。 这个特殊页面应该拦截所有可能的请求-因此听起来像一个servlet过滤器。 渴望并尽早启动Tomcat。 在Spring启动servlet容器通过初始化EmbeddedServletContainerFactory创建的实例EmbeddedServletContainer 。 我们有机会使用EmbeddedServletContainerCustomizer拦截此过程。 容器是在应用程序生命周期的早期创建的但是在整个上下文完成后才开始 。 所以我想我将只在自己的定制器中调用start()就是这样。 不幸的是ConfigurableEmbeddedServletContainer没有公开这样的API所以我不得不像这样装饰EmbeddedServletContainerFactory class ProgressBeanPostProcessor implements BeanPostProcessor {//...Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {if (bean instanceof EmbeddedServletContainerFactory) {return wrap((EmbeddedServletContainerFactory) bean);} else {return bean;}}private EmbeddedServletContainerFactory wrap(EmbeddedServletContainerFactory factory) {return new EmbeddedServletContainerFactory() {Overridepublic EmbeddedServletContainer getEmbeddedServletContainer(ServletContextInitializer... initializers) {final EmbeddedServletContainer container factory.getEmbeddedServletContainer(initializers);log.debug(Eagerly starting {}, container);container.start();return container;}};} } 您可能会认为BeanPostProcessor是一个过大的功能但是稍后它将变得非常有用。 我们在这里所做的是如果遇到从应用程序上下文中被请求的EmbeddedServletContainerFactory 我们将返回一个装饰器该装饰器急切地启动Tomcat。 这给我们带来了相当不稳定的设置即Tomcat接受到尚未初始化的上下文的连接。 因此让我们放置一个servlet过滤器来拦截所有请求直到上下文完成为止。 启动期间拦截请求 我只是通过在Spring上下文中添加FilterRegistrationBean来开始的希望它会拦截传入的请求直到上下文启动为止。 这是徒劳的我不得不等待很长时间直到注册过滤器并准备就绪因此从用户的角度来看应用程序已挂起。 后来我什至尝试使用Servlet API javax.servlet.ServletContext.addFilter() 在Tomcat中直接注册过滤器但是显然必须预先引导整个DispatcherServlet 。 记住我想要的只是来自即将初始化的应用程序的快速反馈。 因此我最终得到了Tomcat的专有API org.apache.catalina.Valve 。 Valve与Servlet过滤器类似但它是Tomcat体系结构的一部分。 Tomcat自己捆绑了多个阀门以处理各种容器功能例如SSL会话群集和X-Forwarded-For处理。 Logback Access也使用此API因此我不会感到内。 阀门看起来像这样 package com.nurkiewicz.progress;import org.apache.catalina.connector.Request; import org.apache.catalina.connector.Response; import org.apache.catalina.valves.ValveBase; import org.apache.tomcat.util.http.fileupload.IOUtils;import javax.servlet.ServletException; import java.io.IOException; import java.io.InputStream;public class ProgressValve extends ValveBase {Overridepublic void invoke(Request request, Response response) throws IOException, ServletException {try (InputStream loadingHtml getClass().getResourceAsStream(loading.html)) {IOUtils.copy(loadingHtml, response.getOutputStream());}} } 阀门通常委托给链中的下一个阀门但是这次我们只为每个单个请求返回static loading.html页面。 注册这样的阀门非常简单Spring Boot为此提供了一个API if (factory instanceof TomcatEmbeddedServletContainerFactory) {((TomcatEmbeddedServletContainerFactory) factory).addContextValves(new ProgressValve()); } 定制阀门原来是一个好主意它从Tomcat立即开始并且非常易于使用。 但是您可能已经注意到即使在应用程序启动后我们也不会放弃提供loading.html 。 那很糟。 Spring上下文可以通过多种方式发出初始化信号例如使用ApplicationListenerContextRefreshedEvent Component class Listener implements ApplicationListenerContextRefreshedEvent {private static final CompletableFutureContextRefreshedEvent promise new CompletableFuture();public static CompletableFutureContextRefreshedEvent initialization() {return promise;}public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {return bean;}Overridepublic void onApplicationEvent(ContextRefreshedEvent event) {promise.complete(event);}} 我知道您的想法是“ static ”吗 但是在Valve内部我根本不想接触Spring上下文因为如果我在错误的时间点从随机线程请​​求某个bean它可能会引入阻塞甚至死锁。 完成promise Valve注销其自身 public class ProgressValve extends ValveBase {public ProgressValve() {Listener.initialization().thenRun(this::removeMyself);}private void removeMyself() {getContainer().getPipeline().removeValve(this);}//...} 这是令人惊讶的干净解决方案当不再需要Valve我们无需从处理管道中删除它而不必为每个请求支付费用。 我不会演示它如何工作以及为什么起作用让我们直接转向目标解决方案。 监控进度 监视Spring应用程序上下文启动的进度非常简单。 另外与基于API和规范驱动的框架如EJB或JSF相反我也惊讶于Spring框架的“可破解性”。 在Spring中我可以简单地实现BeanPostProcessor 以通知每个正在创建和初始化的bean 完整的源代码 package com.nurkiewicz.progress;import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.context.ApplicationListener; import org.springframework.context.event.ContextRefreshedEvent; import rx.Observable; import rx.subjects.ReplaySubject; import rx.subjects.Subject;class ProgressBeanPostProcessor implements BeanPostProcessor, ApplicationListenerContextRefreshedEvent {private static final SubjectString, String beans ReplaySubject.create();public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {return bean;}Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {beans.onNext(beanName);return bean;}Overridepublic void onApplicationEvent(ContextRefreshedEvent event) {beans.onCompleted();}static ObservableString observe() {return beans;} } 每次初始化新bean时我将其名称发布到RxJava的可观察对象中。 整个应用程序初始化后我完成了Observable 。 任何人都可以使用此Observable 例如我们的自定义ProgressValve 完整的源代码 public class ProgressValve extends ValveBase {public ProgressValve() {super(true);ProgressBeanPostProcessor.observe().subscribe(beanName - log.trace(Bean found: {}, beanName),t - log.error(Failed, t),this::removeMyself);}Overridepublic void invoke(Request request, Response response) throws IOException, ServletException {switch (request.getRequestURI()) {case /init.stream:final AsyncContext asyncContext request.startAsync();streamProgress(asyncContext);break;case /health:case /info:response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);break;default:sendHtml(response, loading.html);}}//...} ProgressValve现在变得更复杂了我们还没有完成。 它可以处理多个不同的请求例如我有意在/health和/info Actuator端点上返回503以便该应用程序看起来像在启动期间处于关闭状态。 除了所有其他请求init.stream表明熟悉loading.html 。 /init.stream是特殊的。 这是服务器发送的事件端点它将在每次初始化新bean时推送消息很抱歉上面没有代码 private void streamProgress(AsyncContext asyncContext) throws IOException {final ServletResponse resp asyncContext.getResponse();resp.setContentType(text/event-stream);resp.setCharacterEncoding(UTF-8);resp.flushBuffer();final Subscription subscription ProgressBeanPostProcessor.observe().map(beanName - data: beanName).subscribeOn(Schedulers.io()).subscribe(event - stream(event, asyncContext.getResponse()),e - log.error(Error in observe(), e),() - complete(asyncContext));unsubscribeOnDisconnect(asyncContext, subscription); }private void complete(AsyncContext asyncContext) {stream(event: complete\ndata:, asyncContext.getResponse());asyncContext.complete(); }private void unsubscribeOnDisconnect(AsyncContext asyncContext, final Subscription subscription) {asyncContext.addListener(new AsyncListener() {Overridepublic void onComplete(AsyncEvent event) throws IOException {subscription.unsubscribe();}Overridepublic void onTimeout(AsyncEvent event) throws IOException {subscription.unsubscribe();}Overridepublic void onError(AsyncEvent event) throws IOException {subscription.unsubscribe();}Overridepublic void onStartAsync(AsyncEvent event) throws IOException {}}); }private void stream(String event, ServletResponse response) {try {final PrintWriter writer response.getWriter();writer.println(event);writer.println();writer.flush();} catch (IOException e) {log.warn(Failed to stream, e);} } 这意味着我们可以使用简单的HTTP接口来跟踪Spring应用程序上下文启动的进度 $ curl -v localhost:8090/init.streamGET /init.stream HTTP/1.1User-Agent: curl/7.35.0Host: localhost:8090Accept: */* HTTP/1.1 200 OKContent-Type: text/event-stream;charsetUTF-8Transfer-Encoding: chunkeddata: org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration$EmbeddedTomcatdata: org.springframework.boot.autoconfigure.websocket.WebSocketAutoConfiguration$TomcatWebSocketConfigurationdata: websocketContainerCustomizerdata: org.springframework.boot.autoconfigure.web.ServerPropertiesAutoConfigurationdata: toStringFriendlyJsonNodeToStringConverterdata: org.hibernate.validator.internal.constraintvalidators.bv.NotNullValidatordata: serverPropertiesdata: org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration...data: beanNameViewResolverdata: basicErrorControllerdata: org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration$JpaWebConfiguration$JpaWebMvcConfiguration 该端点将实时初始化请参阅 使用RxJava和SseEmitter的服务器发送的事件 每个初始化的单个bean名称。 有了如此出色的工具我们将构建更强大的 反应性的 在这里我说过 loading.html页面。 花式进度前端 首先我们需要确定哪些Spring bean代表了系统中的哪些子系统 高级组件甚至可能是有限的上下文 。 我使用data-bean自定义属性在HTML内部对此进行了编码 h2 data-beanwebsocketContainerCustomizer classwaitingWeb socket support /h2h2 data-beanmessageConverters classwaitingSpring MVC /h2h2 data-beanmetricFilter classwaitingMetrics /h2h2 data-beanendpointMBeanExporter classwaitingActuator /h2h2 data-beanmongoTemplate classwaitingMongoDB /h2h2 data-beandataSource classwaitingDatabase /h2h2 data-beanentityManagerFactory classwaitingHibernate /h2 CSS classwaiting表示给定的模块尚未初始化即给定的bean尚未出现在SSE流中。 最初所有组件都处于waiting状态。 然后我订阅init.stream并更改CSS类以反映模块状态更改 var source new EventSource(init.stream); source.addEventListener(message, function (e) {var h2 document.querySelector(h2[data-bean e.data ]);if(h2) {h2.className done;} }); 简单吧 显然没有jQuery的人就可以使用纯JavaScript编写前端。 加载所有bean后 Observable在服务器端event: complete SSE发出event: complete 让我们处理一下 source.addEventListener(complete, function (e) {window.location.reload(); }); 因为前端是在应用程序上下文启动时通知的所以我们可以简单地重新加载当前页面。 到那时我们的ProgressValve已经注销因此重新加载将打开真实的应用程序而不是loading.html占位符。 我们的工作完成了。 另外我还计算了启动的bean数量并知道总共有多少bean我用JavaScript对其进行了硬编码请原谅我可以用百分比来计算启动进度。 图片值一千个字下面的屏幕截图向您展示了我们所取得的成果 后续模块启动良好我们不再关注浏览器错误。 以百分比衡量的进度使整个启动进度感觉非常顺利。 最后但并非最不重要的一点是当应用程序启动时我们将自动重定向。 希望您喜欢这个概念证明整个工作示例应用程序都可以在GitHub上找到。 翻译自: https://www.javacodegeeks.com/2015/09/displaying-progress-of-spring-application-startup-in-web-browser.html
http://www.zqtcl.cn/news/891429/

相关文章:

  • qq官方网站进入wordpress调用文章某个分类
  • 南充网站建设设计略奥企业网站管理系统怎么修改密码
  • 网站建设里的知识360云主机可以建设网站吗
  • 创建网站代码上海网络公司查询
  • 电子商务网站建设与管理实训报告百度权重划分等级
  • 网站建设响应式是什么医院网站建设方案策划书
  • 开鲁网站seo不用下载男女做羞羞事动画网站免费
  • 做网站客户需求新乡专业做网站多少钱
  • 邢台建设银行官方网站二维码生成器app下载
  • 自己怎么做网站游戏做网站就是做app
  • 怎样做一元购网站wordpress+淘客代码
  • 网站建设发展现状贵阳有哪些做网站的公司
  • 微博上如何做网站推广蝉知和wordpress
  • 泷澄建设集团网站北京建设执业资格注册网站
  • 门户网站建设情况报告深圳龙岗房价多少钱一平方米
  • 网站建设备案是什么ps培训班
  • 深圳网站推广优化wordpress 运行速度慢
  • 谁能给个网站谢谢发布广东建设工程信息网站
  • 网站建设用户需求分析中国加盟网
  • 建设上线网站seo关键词优化软件排名
  • 郑州手工网站建设公司企业做网站好做吗
  • 苏华建设集团网站产品营销网站
  • 郑州专业做网站的网站收录最好的方法
  • 微信小程序网站建设哪家好视频教学网站开发
  • 个人网站排行网站集约化后如何建设
  • 企业网站维护wordpress特效代码
  • 建设银行网站短信错误6次wordpress新主题去版权
  • 国外 配色网站天猫店购买交易平台
  • 网站推广广告词大全集网站和网络建设自查报告
  • 电子商务网站建设备案须知自己做的网站服务器在哪里