SSM秒杀系统(七)

该部分对秒杀主页进行了优化,秒杀活动开始前,其实就有很多用户访问该页面了。如果这个页面的一些资源,比如 CSS、JS、图片、商品详情等,都访问后端服务器提供,甚至操作数据库,服务肯定会出现不可用的情况。所以一般我们会把这个页面整体进行静态化,降低服务器的压力

十一、频道列表静态化

1.频道列表静态化

由于我们每次访问频道页,也就是主页的时候就会从数据库读取数据进行加载,这样会非常耗时,我们将其静态化为html。这对于哪些修改不频繁的页面非常有用,采用httpclient生成html页面

	@RequestMapping("producehtml")
	public void producehtml(HttpServletRequest req){
		String htmlPath=req.getRealPath("/WEB-INF/html/");
		String contextpath = req.getScheme() +"://" + req.getServerName()  + ":" +req.getServerPort() +req.getContextPath();
		contextpath = contextpath + "/pagehomeAction/tohome";
		
		CloseableHttpClient client = HttpClients.createDefault();
		 HttpGet httpGet = new HttpGet(contextpath); 
		 CloseableHttpResponse response = null;

        try {
            //3.执行请求,获取响应
            response = client.execute(httpGet);
               

            //看请求是否成功,这儿打印的是http状态码
            System.out.println(response.getStatusLine().getStatusCode());
            //4.获取响应的实体内容,就是我们所要抓取得网页内容
            HttpEntity entity = response.getEntity();

            //5.将其打印到控制台上面
            //方法一:使用EntityUtils
            if (entity != null) {
                String html = EntityUtils.toString(entity);
                File file = new File(htmlPath+"/index.html");//存到应用的htmlPath目录下    
                Writer writer = new BufferedWriter(  
                        new OutputStreamWriter(  
                                new FileOutputStream(file), "utf-8"));  
                writer.write(html);  
                writer.flush();  
                writer.close();
            }
            EntityUtils.consume(entity);
        }catch (Exception e) {  
            e.printStackTrace();  
        }  
	}

这会直接在/WEB-INF/html/目录下生成一个与/pagehomeAction/tohome访问的页面相同的一个html页面

由于静态页面没有用户信息,所以通过js添加:

	@RequestMapping("getUser")
	@ResponseBody
	public String getuser(HttpServletRequest req) {
		Msuser msuser = (Msuser)req.getSession().getAttribute("msuser");
		//获取用户名
		String account = "";
		if(msuser!=null) {
			account = msuser.getUseraccount();
		}
		return account;
	}
<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
</head>
<body>
欢迎:<span id="useraccount"></span>
<a href="/YF_MS_WEB/userregiterloginAction/toregiter">注册</a></br>
<a href="/YF_MS_WEB/userregiterloginAction/tologin">登录</a>
<a href="/YF_MS_WEB/userregiterloginAction/exit">退出登录</a>
<a href="/YF_MS_WEB/orderAction/queryorderbyuserid">订单查询</a>
<table border="2">
	<c:forEach items="${list}" var="item">
		<tr>
		<td>${item.producttitle}</td>
		<td>${item.productpicture}</td>
		<td>${item.miaoshaprice}</td>
		<td>${item.originalprice}</td>
		<td>${item.starttime}</td>
		<td>${item.endtime}</td>
		<td><a href="viewproductdetail?id=${item.id}">查看</a></td>
		</tr>
	</c:forEach>
</table>

<script src="/YF_MS_WEB/js/jquery-3.3.1.min.js"></script>
<script type="text/javascript">
	$.ajax({
		type:"get",
		url:"/YF_MS_WEB/pagehomeAction/getUser",
		success:function(msg){
			$("#useraccount").html(msg);
		}
	});
</script>
</body>
</html>

2.分布式定时任务

如果商品更新后如何更新到静态页面呢:我们采用分布式定时任务自动生成html页面,并定时进行更新。我们采用分布式定时任务quartz来实现:

2.1 引入quartz相关的包

<!-- 定时任务引入相关依赖 -->
<dependency>
      <groupId>org.quartz-scheduler</groupId>
      <artifactId>quartz</artifactId>
      <version>2.2.1</version>
    </dependency>
    <dependency>
      <groupId>org.quartz-scheduler</groupId>
      <artifactId>quartz-jobs</artifactId>
      <version>2.2.1</version>
    </dependency>
    <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.2</version>
</dependency>
<dependency>
    <groupId>commons-dbcp</groupId>
    <artifactId>commons-dbcp</artifactId>
    <version>1.4</version>
</dependency>
<dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>4.2.0.RELEASE</version>
    </dependency>
    <dependency>  
            <groupId>org.springframework</groupId>  
            <artifactId>spring-context-support</artifactId>  
            <version>4.2.0.RELEASE</version>  
        </dependency>
    <dependency>  
            <groupId>org.springframework</groupId>  
            <artifactId>spring-tx</artifactId>  
            <version>4.2.0.RELEASE</version>  
        </dependency>

2.2 导入quartz数据库,和数据库配置
在这里插入图片描述
数据库配置:
quartz.properties

#============================================================================
# Configure JobStore
# Using Spring datasource in quartzJobsConfig.xml
# Spring uses LocalDataSourceJobStore extension of JobStoreCMT
#============================================================================
org.quartz.jobStore.useProperties=true
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.isClustered = true
org.quartz.jobStore.clusterCheckinInterval = 5000
org.quartz.jobStore.misfireThreshold = 60000
org.quartz.jobStore.txIsolationLevelReadCommitted = true

# Change this to match your DB vendor
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate


#============================================================================
# Configure Main Scheduler Properties
# Needed to manage cluster instances
#============================================================================
org.quartz.scheduler.instanceId=AUTO
org.quartz.scheduler.instanceName=MY_CLUSTERED_JOB_SCHEDULER
org.quartz.scheduler.rmi.export = false
org.quartz.scheduler.rmi.proxy = false


#============================================================================
# Configure ThreadPool
#============================================================================
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 10
org.quartz.threadPool.threadPriority = 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true

分布式定时任务spring配置:

    <!-- 自动扫描 -->  
    <context:component-scan base-package="com.youfan.*"/>
	
    <bean id="dataSource1" class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
    <property name="url" value="jdbc:mysql://localhost:3306/test2"></property>
    <property name="username" value="root"></property>
    <property name="password" value="123456"></property>
    </bean>
    
    
    <!-- 配置线程池-->
    <bean name="executor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
        <property name="corePoolSize" value="15"/>
        <property name="maxPoolSize" value="25"/>
        <property name="queueCapacity" value="100"/>
    </bean>

    <bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource1"/>
    </bean>

    <!-- 配置调度任务-->
    <bean name="quartzScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <property name="configLocation" value="classpath:quartz.properties"/>
        <property name="dataSource" ref="dataSource1"/>
        <property name="transactionManager" ref="transactionManager"/>

        <!-- 任务唯一的名称,将会持久化到数据库-->
        <property name="schedulerName" value="baseScheduler"/>

        <!-- 每台集群机器部署应用的时候会更新触发器-->
        <property name="overwriteExistingJobs" value="true"/>
        <property name="applicationContextSchedulerContextKey" value="appli22"/>

        <property name="jobFactory">
            <bean class="com.youfan.task.AutowiringSpringBeanJobFactory"/>
        </property>

        <property name="triggers">
            <list>
                <ref bean="printCurrentTimeScheduler"/>
            </list>
        </property>
        <property name="jobDetails">
            <list>
                <ref bean="printCurrentTimeJobs"/>
            </list>
        </property>

        <property name="taskExecutor" ref="executor"/>

    </bean>

    <!-- 配置Job详情 -->
    <bean name="printCurrentTimeJobs" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
        <property name="jobClass" value="com.youfan.task.PrintCurrentTimeJobs"/>
        <!--<property name="jobDataAsMap">
            <map>
                <entry key="clusterQuartz" value="com.aaron.framework.clusterquartz.job.ClusterQuartz"/>
            </map>
        </property>-->
        <property name="durability" value="true"/>
        <property name="requestsRecovery" value="false"/>
    </bean>

    <!-- 配置触发时间 -->
    <bean name="printCurrentTimeScheduler" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
        <property name="jobDetail" ref="printCurrentTimeJobs"/>
        <property name="cronExpression">
            <value>0/10 * * * * ?</value>
        </property>
        <property name="timeZone">
            <value>GMT+8:00</value>
        </property>
    </bean>

    <!-- 分布式事务配置 end -->

2.3 自动生成和更新html

还是调用pagehomeAction/producehtml来生成

@Controller
public class ProducehtmlTask
{
   
	public void producehtml(){
		String url = "http://127.0.0.1:8080/YF_MS_WEB/pagehomeAction/producehtml";
		
		CloseableHttpClient client = HttpClients.createDefault();
		 HttpGet httpGet = new HttpGet(url); 
		 CloseableHttpResponse response = null;

        try {
            //3.执行请求,获取响应
            response = client.execute(httpGet);
               

            //看请求是否成功,这儿打印的是http状态码
            System.out.println("ProducehtmlTask=="+response.getStatusLine().getStatusCode());
            
        }catch (Exception e) {  
            e.printStackTrace();  
        }  
	}
}

2.4 这样服务器启动成功后,如果数据库数据被修改,我们访问的html/index.html页面每隔10s更新一次,也会自动修改

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值