乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Google App Engine性能調(diào)優(yōu) - 頁(yè)面性能優(yōu)化 - YongPei - JavaEye技術(shù)網(wǎng)站

       ShangShujie 2010-07-14

      GAE提供了簡(jiǎn)單實(shí)用的API和開(kāi)發(fā)工具,結(jié)合已有的 開(kāi)發(fā)框架,Java開(kāi)發(fā)人員可以很容易開(kāi)發(fā)出自己的業(yè)務(wù)應(yīng)用系統(tǒng)。

      本次先介紹頁(yè)面部分的性能優(yōu)化技巧,只需要進(jìn)行簡(jiǎn)單的 設(shè)置和少量的編碼,即可獲得不錯(cuò)的性能提高。后續(xù)的文章

      文中提到的技巧已經(jīng)在本博客取得驗(yàn)證,從后來(lái)的統(tǒng)計(jì)數(shù)據(jù)中 可以看到,首頁(yè)的處理時(shí)間從平均400ms減少到了平均26ms,性能提高了15倍!

      發(fā)表于:http://hoverblog./blog?key=aglob3ZlcmJsb2dyCwsSBEJsb2cYuRcM

      指定GAE的靜態(tài)文件配置

      在一般的httpd + tomcat的架構(gòu)中,客戶端對(duì)圖片、css文件以及js文件等靜態(tài)資源文件,會(huì)根據(jù)文件的lsat modified屬性,盡量只會(huì)請(qǐng)求一次,只有當(dāng)文件進(jìn)行了更新之后,才會(huì)重新請(qǐng)求新的文件。

      但是在GAE里面,如果你不進(jìn)行靜態(tài)文件的設(shè)置,默認(rèn) 情況下,是無(wú)法享受上面所提的好處的。下面來(lái)看看設(shè)置的文件/WEB-INF/appengine-web.xml:

      <?xml version="1.0" encoding="utf-8"?>
      <appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
      <application>yourappid</application>
      <version>1</version>
      <static-files>
      <include path="/**.jpg"/>
      <include path="/**.png"/>
      <include path="/**.gif"/>
      <include path="/**.ico"/>
      <include path="/**.css"/>
      <include path="/**.js"/>
      </static-files>
      </appengine-web-app>
      

      進(jìn)行了上面的設(shè)置之后,你的應(yīng)用可以得到較為明顯的性 能提升。

      利用Memcache服務(wù)進(jìn)行頁(yè)面緩存

      GAE提供了Memcache服務(wù),可以將經(jīng)常使用到 數(shù)據(jù)暫時(shí)存儲(chǔ)在Memcache中,可以大大減少請(qǐng)求的處理時(shí)間,提高頁(yè)面響應(yīng)速度。下面提供幾個(gè)代碼例子,利用Servlet Filter技術(shù),可以對(duì)經(jīng)常訪問(wèn)的頁(yè)面進(jìn)行緩存操作。

      CacheSingleton.java

      package hover.blog.servlet;
      import javax.cache.Cache;
      import javax.cache.CacheException;
      import javax.cache.CacheFactory;
      import javax.cache.CacheManager;
      import javax.servlet.ServletException;
      import java.util.Map;
      /**
      * @author Hover
      * @version 1.0
      */
      public class CacheSingleton {
      private static final CacheSingleton instance = new CacheSingleton();
      private Cache cache;
      private CacheSingleton() {
      }
      public static CacheSingleton getInstance() {
      return instance;
      }
      public void init(Map props) throws ServletException {
      try {
      CacheFactory factory = CacheManager.getInstance().getCacheFactory();
      cache = factory.createCache(props);
      } catch (CacheException e) {
      throw new ServletException("cache error: " + e.getMessage(), e);
      }
      }
      public Cache getCache() {
      return cache;
      }
      public void clear() {
      if (cache != null) {
      cache.clear();
      }
      }
      }
      

      因需要在多處地方訪問(wèn)Cache,因此這里使用了 Singleton模式,可以在不同的Action中訪問(wèn)同一個(gè)Cache實(shí)例。

      WebCacheFilter

      WebCacheFilter.java

      package hover.blog.servlet;
      import javax.cache.Cache;
      import javax.servlet.*;
      import javax.servlet.http.Cookie;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      import java.io.BufferedOutputStream;
      import java.io.ByteArrayOutputStream;
      import java.io.IOException;
      import java.util.Collections;
      import java.util.List;
      /**
      * @author Hover
      * @version 1.0
      */
      @SuppressWarnings("unchecked")
      public class WebCacheFilter implements Filter {
      public static final String PAGE_PREFIX = "/page";
      public void init(FilterConfig config) throws ServletException {
      CacheSingleton.getInstance().init(Collections.emptyMap());
      }
      public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
      FilterChain chain) throws IOException, ServletException {
      HttpServletRequest request = (HttpServletRequest) servletRequest;
      HttpServletResponse response = (HttpServletResponse) servletResponse;
      Cache cache = CacheSingleton.getInstance().getCache();
      if ("post".equalsIgnoreCase(request.getMethod()) || cache == null) {
      chain.doFilter(servletRequest, servletResponse);
      } else {
      String requestPath = request.getRequestURI();
      String queryString = request.getQueryString();
      if (queryString != null && queryString.length() > 0) {
      requestPath += "?" + queryString;
      }
      String cachePath = PAGE_PREFIX + requestPath;
      PageInfo page = null;
      try {
      page = (PageInfo) cache.get(cachePath);
      }
      catch (Exception e) {
      // type mis-match
      }
      if (page == null) {  // on cache content
      ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
      GenericResponseWrapper wrapper = new GenericResponseWrapper(response, byteArrayOutputStream);
      chain.doFilter(request, wrapper);
      wrapper.flush();
      page = new PageInfo(wrapper.getStatus(), wrapper.getContentType(), wrapper.getHeaders(),
      wrapper.getCookies(), byteArrayOutputStream.toByteArray());
      if (page.getStatus() == HttpServletResponse.SC_OK) {
      cache.put(cachePath, page);
      }
      }
      response.setStatus(page.getStatus());
      String contentType = page.getContentType();
      if (contentType != null && contentType.length() > 0) {
      response.setContentType(contentType);
      }
      for (Cookie cookie : (List) page.getCookies()) {
      response.addCookie(cookie);
      }
      for (String[] header : (List) page.getResponseHeaders()) {
      response.setHeader(header[0], header[1]);
      }
      response.setContentLength(page.getBody().length);
      BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
      out.write(page.getBody());
      out.flush();
      }
      }
      public void destroy() {
      }
      }
      

      在初始化的時(shí)候,調(diào)用 CacheSingleton.init()方法,初始化Memecache的調(diào)用接口。

      WebCacheFilter只處理HTTP GET請(qǐng)求,對(duì)后臺(tái)數(shù)據(jù)的修改、刪除、新增等操作,應(yīng)該使用HTTP POST方式來(lái)提交數(shù)據(jù)。

      下面將此Filter所用到的其他輔助類列在下面:

      FilterServletOutputStream.java

      package hover.blog.servlet;
      import javax.servlet.ServletOutputStream;
      import java.io.IOException;
      import java.io.OutputStream;
      /**
      * @author Hover
      * @version 1.0
      */
      public class FilterServletOutputStream extends ServletOutputStream {
      private OutputStream stream;
      public FilterServletOutputStream(final OutputStream stream) {
      this.stream = stream;
      }
      /**
      * Writes to the stream.
      */
      public void write(final int b) throws IOException {
      stream.write(b);
      }
      /**
      * Writes to the stream.
      */
      public void write(final byte[] b) throws IOException {
      stream.write(b);
      }
      /**
      * Writes to the stream.
      */
      public void write(final byte[] b, final int off, final int len) throws IOException {
      stream.write(b, off, len);
      }
      }
      

      GenericResponseWrapper.java

      package hover.blog.servlet;
      import javax.servlet.ServletOutputStream;
      import javax.servlet.http.Cookie;
      import javax.servlet.http.HttpServletResponse;
      import javax.servlet.http.HttpServletResponseWrapper;
      import java.io.*;
      import java.util.ArrayList;
      import java.util.Collection;
      import java.util.List;
      import java.util.logging.Logger;
      /**
      * @author Hover
      * @version 1.0
      */
      @SuppressWarnings("unchecked")
      public class GenericResponseWrapper extends HttpServletResponseWrapper implements Serializable {
      private static final Logger LOG = Logger.getLogger(GenericResponseWrapper.class.getName());
      private int statusCode = SC_OK;
      private int contentLength;
      private String contentType;
      private final List headers = new ArrayList();
      private final List cookies = new ArrayList();
      private ServletOutputStream outstr;
      private PrintWriter writer;
      /**
      * Creates a GenericResponseWrapper
      */
      public GenericResponseWrapper(final HttpServletResponse response, final OutputStream outstr) {
      super(response);
      this.outstr = new FilterServletOutputStream(outstr);
      }
      /**
      * Gets the outputstream.
      */
      public ServletOutputStream getOutputStream() {
      return outstr;
      }
      /**
      * Sets the status code for this response.
      */
      public void setStatus(final int code) {
      statusCode = code;
      super.setStatus(code);
      }
      /**
      * Send the error. If the response is not ok, most of the logic is bypassed and the error is sent raw
      * Also, the content is not cached.
      *
      * @param i      the status code
      * @param string the error message
      * @throws IOException
      */
      public void sendError(int i, String string) throws IOException {
      statusCode = i;
      super.sendError(i, string);
      }
      /**
      * Send the error. If the response is not ok, most of the logic is bypassed and the error is sent raw
      * Also, the content is not cached.
      *
      * @param i the status code
      * @throws IOException
      */
      public void sendError(int i) throws IOException {
      statusCode = i;
      super.sendError(i);
      }
      /**
      * Send the redirect. If the response is not ok, most of the logic is bypassed and the error is sent raw.
      * Also, the content is not cached.
      *
      * @param string the URL to redirect to
      * @throws IOException
      */
      public void sendRedirect(String string) throws IOException {
      statusCode = HttpServletResponse.SC_MOVED_TEMPORARILY;
      super.sendRedirect(string);
      }
      /**
      * Sets the status code for this response.
      */
      public void setStatus(final int code, final String msg) {
      statusCode = code;
      LOG.warning("Discarding message because this method is deprecated.");
      super.setStatus(code);
      }
      /**
      * Returns the status code for this response.
      */
      public int getStatus() {
      return statusCode;
      }
      /**
      * Sets the content length.
      */
      public void setContentLength(final int length) {
      this.contentLength = length;
      super.setContentLength(length);
      }
      /**
      * Gets the content length.
      */
      public int getContentLength() {
      return contentLength;
      }
      /**
      * Sets the content type.
      */
      public void setContentType(final String type) {
      this.contentType = type;
      super.setContentType(type);
      }
      /**
      * Gets the content type.
      */
      public String getContentType() {
      return contentType;
      }
      /**
      * Gets the print writer.
      */
      public PrintWriter getWriter() throws IOException {
      if (writer == null) {
      writer = new PrintWriter(new OutputStreamWriter(outstr, getCharacterEncoding()), true);
      }
      return writer;
      }
      /**
      * Adds a header.
      */
      public void addHeader(final String name, final String value) {
      final String[] header = new String[]{name, value};
      headers.add(header);
      super.addHeader(name, value);
      }
      /**
      * @see #addHeader
      */
      public void setHeader(final String name, final String value) {
      addHeader(name, value);
      }
      /**
      * Gets the headers.
      */
      public List getHeaders() {
      return headers;
      }
      /**
      * Adds a cookie.
      */
      public void addCookie(final Cookie cookie) {
      cookies.add(cookie);
      super.addCookie(cookie);
      }
      /**
      * Gets all the cookies.
      */
      public List getCookies() {
      return cookies;
      }
      /**
      * Flushes buffer and commits response to client.
      */
      public void flushBuffer() throws IOException {
      flush();
      super.flushBuffer();
      }
      /**
      * Resets the response.
      */
      public void reset() {
      super.reset();
      cookies.clear();
      headers.clear();
      statusCode = SC_OK;
      contentType = null;
      contentLength = 0;
      }
      /**
      * Resets the buffers.
      */
      public void resetBuffer() {
      super.resetBuffer();
      }
      /**
      * Flushes all the streams for this response.
      */
      public void flush() throws IOException {
      if (writer != null) {
      writer.flush();
      }
      outstr.flush();
      }
      }
      

      PageInfo.java

      package hover.blog.servlet;
      import java.io.Serializable;
      import java.util.List;
      /**
      * @author Hover
      * @version 1.0
      */
      public class PageInfo implements Serializable {
      private int status;
      private String contentType;
      private List responseHeaders;
      private List cookies;
      private byte[] body;
      public PageInfo() {
      }
      public PageInfo(int status, String contentType, List responseHeaders, List cookies, byte[] body) {
      this.status = status;
      this.contentType = contentType;
      this.responseHeaders = responseHeaders;
      this.cookies = cookies;
      this.body = body;
      }
      public int getStatus() {
      return status;
      }
      public void setStatus(int status) {
      this.status = status;
      }
      public String getContentType() {
      return contentType;
      }
      public void setContentType(String contentType) {
      this.contentType = contentType;
      }
      public List getResponseHeaders() {
      return responseHeaders;
      }
      public void setResponseHeaders(List responseHeaders) {
      this.responseHeaders = responseHeaders;
      }
      public List getCookies() {
      return cookies;
      }
      public void setCookies(List cookies) {
      this.cookies = cookies;
      }
      public byte[] getBody() {
      return body;
      }
      public void setBody(byte[] body) {
      this.body = body;
      }
      }
      

      在web.xml中配置WebCacheFilter

      在web.xml中,配置 WebCacheFilter,對(duì)經(jīng)常訪問(wèn)的頁(yè)面進(jìn)行緩存。下面是我的博客的配置:

      <?xml version="1.0" encoding="UTF-8"?>
      <web-app xmlns="http://java./xml/ns/javaee"
      xmlns:xsi="http://www./2001/XMLSchema-instance"
      xsi:schemaLocation="http://java./xml/ns/javaee
      http://java./xml/ns/javaee/web-app_2_5.xsd"
      version="2.5">
      <filter>
      <filter-name>webCache</filter-name>
      <filter-class>hover.blog.servlet.WebCacheFilter</filter-class>
      </filter>
      <filter-mapping>
      <filter-name>webCache</filter-name>
      <url-pattern>/main</url-pattern>
      </filter-mapping>
      <filter-mapping>
      <filter-name>webCache</filter-name>
      <url-pattern>/blog</url-pattern>
      </filter-mapping>
      <filter-mapping>
      <filter-name>webCache</filter-name>
      <url-pattern>/category</url-pattern>
      </filter-mapping>
      </web-app>
      

      頁(yè)面緩存的使用限制

      WebCacheFilter會(huì)緩存整個(gè)頁(yè)面的全部元 素,如果頁(yè)面中存在用戶相關(guān)的代碼,例如根據(jù)用戶的身份不同而現(xiàn)實(shí)不同的內(nèi)容的話,可能會(huì)出現(xiàn)不希望出現(xiàn)的后果。

      假設(shè)你的頁(yè)面中,判斷如果是管理員的話,顯示編輯鏈 接:

      jsp文件:
      <s:if test="admin">
      <a href="edit-blog?key=<s:property value="key"/>">
      <s:text name="edit"/>
      </a>
      </s:if>
      

      如果管理員先訪問(wèn)了頁(yè)面,則緩存中保存的頁(yè)面中,就包 含了“編輯”的鏈接。當(dāng)另外一個(gè)普通用戶訪問(wèn)同一個(gè)url時(shí),從頁(yè)面緩存中獲得了前面管理員所看到的頁(yè)面,因?yàn)椋胀ㄓ脩粢部吹搅?#8220;編輯”的鏈接。

      因此,在利用WebCacheFilter進(jìn)行緩存的 頁(yè)面中,盡量避免太多的動(dòng)態(tài)屬性顯示。數(shù)據(jù)的編輯、維護(hù)工作應(yīng)該在專門的頁(yè)面中進(jìn)行。

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多