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

团购做的好的网站有哪些行业门户网站运营

团购做的好的网站有哪些,行业门户网站运营,南岸网站建设,服装设计投稿平台1.简介 最近我司上线使用了分布式任务调度框架#xff1a;XXL-JOB#xff0c;方便对任务的管理控制。本来一开始就想讲述一下该框架#xff0c;但是在学习了解过程中发现该框架式基于Quartz思想开发实现的#xff0c;Quartz 是一个很火的开源任务调度框架#xff0c;完全…1.简介 最近我司上线使用了分布式任务调度框架XXL-JOB方便对任务的管理控制。本来一开始就想讲述一下该框架但是在学习了解过程中发现该框架式基于Quartz思想开发实现的Quartz 是一个很火的开源任务调度框架完全由Java写成可以说是 Java 定时任务领域的老大哥或者说参考标准所以在这里先讲讲Quartz框架。 1.1.Quartz是什么 Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目是完全由java开发的一个开源的任务日程管理系统“任务进度管理器”就是一个在预先确定被纳入日程的时间到达时负责执行或者通知其他软件组件的系统。其功能类似于java.util.Timer。但是相较于Timer Quartz增加了很多功能作为一个优秀的开源调度框架Quartz具有以下特点 强大的调度功能例如支持丰富多样的调度方法可以满足各种常规及特殊需求灵活的应用方式支持调度数据的多种存储方式分布式和集群能力 1.2.存储方式 RAMJobStore和JDBCJobStore 两者对比如下 类型优点缺点RAMJobStore不要外部数据库配置容易运行速度快因为调度程序信息是存储在被分配给JVM的内存里面所以当应用程序停止运行时所有调度信息将被丢失。另外因为存储到JVM内存里面所以可以存储多少个Job和Trigger将会受到限制JDBCJobStore支持集群因为所有的任务信息都会保存到数据库中可以控制事物还有就是如果应用服务器关闭或者重启任务信息都不会丢失并且可以恢复因服务器关闭或者重启而导致执行失败的任务运行速度的快慢取决与连接数据库的快慢 根据上面知道要想支持分布式集群必须属于JDBCJobStore其需要借助数据库MySQL数据库初始化表SQL下载tables表描述说明如下 表名说明qrtz_blob_triggersTrigger作为Blob类型存储(用于Quartz用户用JDBC创建他们自己定制的Trigger类型JobStore 并不知道如何存储实例的时候)qrtz_calendars以Blob类型存储Quartz的Calendar日历信息 quartz可配置一个日历来指定一个时间范围qrtz_cron_triggers存储Cron Trigger包括Cron表达式和时区信息qrtz_fired_triggers存储与已触发的Trigger相关的状态信息以及相联Job的执行信息qrtz_job_details存储每一个已配置的Job的详细信息qrtz_locks存储程序的非观锁的信息(假如使用了悲观锁)qrtz_paused_trigger_graps存储已暂停的Trigger组的信息qrtz_scheduler_state存储少量的有关 Scheduler的状态信息和别的 Scheduler 实例(假如是用于一个集群中)qrtz_simple_triggers存储简单的 Trigger包括重复次数间隔以及已触的次数qrtz_triggers存储已配置的 Trigger的信息 项目推荐基于SpringBoot2.x、SpringCloud和SpringCloudAlibaba企业级系统架构底层框架封装解决业务开发时常见的非功能性需求防止重复造轮子方便业务快速开发和企业技术栈框架统一管理。引入组件化的思想实现高内聚低耦合并且高度可配置化做到可插拔。严格控制包依赖和统一版本管理做到最少化依赖。注重代码规范和注释非常适合个人学习和企业使用 Github地址https://github.com/plasticene/plasticene-boot-starter-parent Gitee地址https://gitee.com/plasticene3/plasticene-boot-starter-parent 微信公众号Shepherd进阶笔记 交流探讨群Shepherd_126 2.springboot整合示例 springboot整合quartz非常简单这里我们演示集群模式所以使用JDBCJobStore相关所需依赖如下 !-- 实现对 Quartz 的自动化配置 --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-quartz/artifactId/dependency!-- 实现对数据库连接池的自动化配置 --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-jdbc/artifactId/dependencydependency !-- 本示例我们使用 MySQL --groupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion5.1.48/version/dependency 在创建任务之前我们需要下载上面SQL语句执行一下这里建表可以和业务数据库在同一个库也可以单独放到一个数据库如果单独建库建表那么业务服务就是多数据源了需要重新封装数据源连接。如下的多数据源配置 Configuration public class DataSourceConfiguration {/*** 创建 user 数据源的配置对象*/PrimaryBean(name userDataSourceProperties)ConfigurationProperties(prefix spring.datasource.user) // 读取 spring.datasource.user 配置到 DataSourceProperties 对象public DataSourceProperties userDataSourceProperties() {return new DataSourceProperties();}/*** 创建 user 数据源*/PrimaryBean(name userDataSource)ConfigurationProperties(prefix spring.datasource.user.hikari) // 读取 spring.datasource.user 配置到 HikariDataSource 对象public DataSource userDataSource() {// 获得 DataSourceProperties 对象DataSourceProperties properties this.userDataSourceProperties();// 创建 HikariDataSource 对象return createHikariDataSource(properties);}/*** 创建 quartz 数据源的配置对象*/Bean(name quartzDataSourceProperties)ConfigurationProperties(prefix spring.datasource.quartz) // 读取 spring.datasource.quartz 配置到 DataSourceProperties 对象public DataSourceProperties quartzDataSourceProperties() {return new DataSourceProperties();}/*** 创建 quartz 数据源*/Bean(name quartzDataSource)ConfigurationProperties(prefix spring.datasource.quartz.hikari)QuartzDataSourcepublic DataSource quartzDataSource() {// 获得 DataSourceProperties 对象DataSourceProperties properties this.quartzDataSourceProperties();// 创建 HikariDataSource 对象return createHikariDataSource(properties);}private static HikariDataSource createHikariDataSource(DataSourceProperties properties) {// 创建 HikariDataSource 对象HikariDataSource dataSource properties.initializeDataSourceBuilder().type(HikariDataSource.class).build();// 设置线程池名if (StringUtils.hasText(properties.getName())) {dataSource.setPoolName(properties.getName());}return dataSource;}}为了快速简单测试我们把Quartz的建表放到业务库一起然后如下配置即可 spring:datasource:url: jdbc:mysql://10.10.0.10:3306/ptc_job?useSSLfalseuseUnicodetruecharacterEncodingUTF-8driver-class-name: com.mysql.jdbc.Driverusername: rootpassword: root# Quartz 的配置对应 QuartzProperties 配置类quartz:scheduler-name: clusteredScheduler # Scheduler 名字。默认为 schedulerNamejob-store-type: jdbc # Job 存储器类型。默认为 memory 表示内存可选 jdbc 使用数据库。auto-startup: true # Quartz 是否自动启动startup-delay: 0 # 延迟 N 秒启动wait-for-jobs-to-complete-on-shutdown: true # 应用关闭时是否等待定时任务执行完成。默认为 false 建议设置为 trueoverwrite-existing-jobs: true # 是否覆盖已有 Job 的配置注意为false时修改已存在的任务调度cron周期不生效jdbc: # 使用 JDBC 的 JobStore 的时候JDBC 的配置initialize-schema: never # 是否自动使用 SQL 初始化 Quartz 表结构。这里设置成 never 我们手动创建表结构。properties: # 添加 Quartz Scheduler 附加属性更多可以看 http://www.quartz-scheduler.org/documentation/2.4.0-SNAPSHOT/configuration.html 文档org:quartz:# JobStore 相关配置jobStore:# 数据源名称dataSource: quartzDataSource # 使用的数据源class: org.quartz.impl.jdbcjobstore.JobStoreTX # JobStore 实现类driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegatetablePrefix: QRTZ_ # Quartz 表前缀isClustered: true # 是集群模式clusterCheckinInterval: 1000useProperties: false# 线程池相关配置threadPool:threadCount: 25 # 线程池大小。默认为 10 。threadPriority: 5 # 线程优先级class: org.quartz.simpl.SimpleThreadPool # 线程池类型 创建任务Job1 DisallowConcurrentExecution public class Job1 extends QuartzJobBean {private Logger logger LoggerFactory.getLogger(getClass());private static SimpleDateFormat fullDateFormat new SimpleDateFormat(yyyy-MM-dd HH:mm:ss);private final AtomicInteger count new AtomicInteger();Autowiredprivate DemoService demoService;private String k1;public void setK1(String k1) {this.k1 k1;}Overrideprotected void executeInternal(JobExecutionContext context) {logger.info([job1的执行了时间: {}, k1{}, count{}, demoService{}], fullDateFormat.format(new Date()), k1,count.incrementAndGet(), demoService);}}继承 QuartzJobBean 抽象类实现 #executeInternal(JobExecutionContext context) 方法执行自定义的定时任务的逻辑。 QuartzJobBean 实现了 org.quartz.Job 接口提供了 Quartz 每次创建 Job 执行定时逻辑时将该 JobDataMap数据进行依赖属性注入到Job Bean中。 // QuartzJobBean.javapublic final void execute(JobExecutionContext context) throws JobExecutionException {try {// 将当前对象包装成 BeanWrapper 对象BeanWrapper bw PropertyAccessorFactory.forBeanPropertyAccess(this);// 设置属性到 bw 中MutablePropertyValues pvs new MutablePropertyValues();pvs.addPropertyValues(context.getScheduler().getContext());pvs.addPropertyValues(context.getMergedJobDataMap());bw.setPropertyValues(pvs, true);} catch (SchedulerException ex) {throw new JobExecutionException(ex);}// 执行提供给子类实现的抽象方法this.executeInternal(context); }protected abstract void executeInternal(JobExecutionContext context) throws JobExecutionException;注入Job任务配置如下 Beanpublic JobDetail job1() {return JobBuilder.newJob(Job1.class).withIdentity(job1).storeDurably() .usingJobData(k1, v1).build();}Beanpublic Trigger simpleJobTrigger() {// 简单的调度计划的构造器SimpleScheduleBuilder scheduleBuilder SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(30) // 频率 30s执行一次。.repeatForever(); // 次数。// Trigger 构造器return TriggerBuilder.newTrigger().forJob(job1()) .withIdentity(job1Trigger) .withSchedule(scheduleBuilder) .build();}这时候启动项目查看日志如下 2022-09-20 23:17:33.500 INFO 18982 --- [eduler_Worker-2] : [job1的执行了时间: 2022-09-20 23:17:33, k1v1, count1, demoServiceDemoService3258ebff] 2022-09-20 23:18:03.463 INFO 18982 --- [eduler_Worker-3] : [job1的执行了时间: 2022-09-20 23:18:03, k1v1, count1, demoServiceDemoService3258ebff] 2022-09-20 23:18:33.439 INFO 18982 --- [eduler_Worker-4] : [job1的执行了时间: 2022-09-20 23:18:33, k1v1, count1, demoServiceDemoService3258ebff] 2022-09-20 23:19:03.448 INFO 18982 --- [eduler_Worker-5] : [job1的执行了时间: 2022-09-20 23:19:03, k1v1, count1, demoServiceDemoService3258ebff]从计数器count可以看出每次 Job0 都会被 Quartz 创建出一个新的 Job 对象执行任务但是DemoService属性值相同是Spring单例bean同时JobData的数据自动映射注入到任务bean属性上。 上面是通过简单调度器simpleSchedule指定频率执行任务当然我也可以使用主流的基于cron表达式实现任务周期执行 Beanpublic JobDetail job1() {return JobBuilder.newJob(Job1.class).withIdentity(job1).storeDurably() .usingJobData(k1, v1).build();}Beanpublic Trigger cronJobTrigger() {// 每隔1分钟执行一次CronScheduleBuilder scheduleBuilder CronScheduleBuilder.cronSchedule(0 0/1 * * * ? *);// Trigger 构造器return TriggerBuilder.newTrigger().forJob(job1()) .withIdentity(job1Trigger) .withSchedule(scheduleBuilder) .build();}任务调度执行结果这里就不再展示了和上面一回事。 3.实现原理 Quartz 是通过 Scheduler 调度器来进行任务的操作它可以把任务 JobDetail 和触发器 Trigger 加入任务池中可以把任务删除也可以把任务停止scheduler 把这些任务和触发器放到一个 JobStore 中这里 jobStore 有内存形式的也有持久化形式的当然也可以自定义扩展成独立的服务。 Quartz内部会通过一个调度线程 QuartzSchedulerThread 不断到 JobStore 中找出下次需要执行的任务并把这些任务封装放到一个线程池 ThreadPool 中运行组件结构如下图 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MTzKZywl-1691461202634)(https://markdown-file-zfj.oss-cn-hangzhou.aliyuncs.com/Quartz%E6%9E%B6%E6%9E%84%E5%9B%BE.png)] 核心类 QuartzSchedulerThread负责执行向QuartzScheduler注册的触发Trigger的工作的线程。 ThreadPoolScheduler使用一个线程池作为任务运行的基础设施任务通过共享线程池中的线程提供运行效率。 QuartzSchedulerResources包含创建QuartzScheduler实例所需的所有资源JobStoreThreadPool等。 SchedulerFactory 提供用于获取调度程序实例的客户端可用句柄的机制。 JobStore 通过类实现的接口这些类要为org.quartz.core.QuartzScheduler的使用提供一个org.quartz.Job和org.quartz.Trigger存储机制。作业和触发器的存储应该以其名称和组的组合为唯一性。 QuartzScheduler 这是Quartz的核心它是org.quartz.Scheduler接口的间接实现包含调度org.quartz.Jobs注册org.quartz.JobListener实例等的方法。 Scheduler 这是Quartz Scheduler的主要接口代表一个独立运行容器。调度程序维护JobDetails和触发器的注册表。 一旦注册调度程序负责执行作业当他们的相关联的触发器触发当他们的预定时间到达时。 Trigger 具有所有触发器通用属性的基本接口描述了job执行的时间出发规则。 - 使用TriggerBuilder实例化实际触发器。 JobDetail 传递给定作业实例的详细信息属性。 JobDetails将使用JobBuilder创建/定义。 Job要由表示要执行的“作业”的类实现的接口。只有一个方法 void execute(jobExecutionContext context) (jobExecutionContext 提供调度上下文各种信息运行时数据保存在jobDataMap中) Job有个子接口StatefulJob ,代表有状态任务。有状态任务不可并发前次任务没有执行完后面任务处于阻塞等到。 下面展示原生的Quartz创建任务、绑定触发器、注册任务和定时器、启动调度器 /*** 原生创建任务流程示例有助于分析quartz实现原理* throws SchedulerException*/public static void test() throws SchedulerException {//1.创建Scheduler的工厂SchedulerFactory sf new StdSchedulerFactory();//2.从工厂中获取调度器实例Scheduler scheduler sf.getScheduler();//3.创建JobDetailJobDetail jb JobBuilder.newJob(Job1.class).withDescription(this is a job) //job的描述.withIdentity(job1, test-job) //job 的name和group.build();//任务运行的时间SimpleSchedule类型触发器有效long time System.currentTimeMillis() 3*1000L; //3秒后启动任务Date statTime new Date(time);//4.创建Trigger//使用SimpleScheduleBuilder或者CronScheduleBuilderTrigger t TriggerBuilder.newTrigger().withDescription().withIdentity(job1Trigger, job1TriggerGroup)//.withSchedule(SimpleScheduleBuilder.simpleSchedule()).startAt(statTime) //默认当前时间启动.withSchedule(CronScheduleBuilder.cronSchedule(0/10 * * * * ?)) //10秒执行一次.build();//5.注册任务和定时器scheduler.scheduleJob(jb, t);//源码分析//6.启动 调度器scheduler.start();}public static void main(String[] args) throws SchedulerException {test();} 接下来对主要三个步骤创建调度器、注册任务和触发器、启动调度器执行任务进行分析 调度器初始化 SchedulerFactory sf new StdSchedulerFactory();Scheduler scheduler sf.getScheduler();SchedulerFacotory 是创建调度器的工厂接口它有两个实现StdSchedulerFacotory 根据配置文件来创建 SchedulerDirectSchedulerFactory 主要通过编码对 Scheduler 控制通常为了侵入性更小、实现更方便我们用 StdSchedulerFacotory 类型来创建 StdSchedulerquartz.properties 里面的配置都对应到这个 StdSchedulerFactory 中所以对某个配置不明白已经该配置的默认值可以看 StdSchedulerFactory 中获取配置的代码。 从sf.getScheduler()入手进入StdSchedulerFacotory可以看到该方法逻辑 public Scheduler getScheduler() throws SchedulerException {// 第一步加载配置文件System的properties覆盖前面的配置if (cfg null) {initialize();}SchedulerRepository schedRep SchedulerRepository.getInstance();Scheduler sched schedRep.lookup(getSchedulerName());if (sched ! null) {if (sched.isShutdown()) {schedRep.remove(getSchedulerName());} else {return sched;}}// 第二步初始化生成schedulersched instantiate();return sched;}这里一共完成两个逻辑加载配置和生成scheduler接下来进入核心方法instantiate()这里面逻辑很多其核心操作就是初始化各种调度所需要的对象比如线程池、JobStore等等最后把上面创建的对象放到 QuartzSchedulerResources 中并把线程池起来这个相当于 QuartzScheduler 的资源存放处, 方法相关代码如下 private Scheduler instantiate() throws SchedulerException{......// 要初始化的对象JobStore js null;ThreadPool tp null;QuartzScheduler qs null;DBConnectionManager dbMgr null;String instanceIdGeneratorClass null;Properties tProps null;String userTXLocation null;boolean wrapJobInTx false;boolean autoId false;long idleWaitTime -1;long dbFailureRetry 15000L; // 15 secsString classLoadHelperClass;String jobFactoryClass;ThreadExecutor threadExecutor;.....QuartzSchedulerResources rsrcs new QuartzSchedulerResources();rsrcs.setName(schedName);rsrcs.setThreadName(threadName);rsrcs.setInstanceId(schedInstId);rsrcs.setJobRunShellFactory(jrsf);rsrcs.setMakeSchedulerThreadDaemon(makeSchedulerThreadDaemon);rsrcs.setThreadsInheritInitializersClassLoadContext(threadsInheritInitalizersClassLoader);rsrcs.setRunUpdateCheck(!skipUpdateCheck);rsrcs.setBatchTimeWindow(batchTimeWindow);rsrcs.setMaxBatchSize(maxBatchSize);rsrcs.setInterruptJobsOnShutdown(interruptJobsOnShutdown);rsrcs.setInterruptJobsOnShutdownWithWait(interruptJobsOnShutdownWithWait);rsrcs.setJMXExport(jmxExport);rsrcs.setJMXObjectName(jmxObjectName);//这个线程执行者用于后面启动调度线程rsrcs.setThreadExecutor(threadExecutor);threadExecutor.initialize();rsrcs.setThreadPool(tp);if (tp instanceof SimpleThreadPool) {if (threadsInheritInitalizersClassLoader)((SimpleThreadPool) tp).setThreadsInheritContextClassLoaderOfInitializingThread(threadsInheritInitalizersClassLoader);}//执行线程池启动tp.initialize();tpInited true;rsrcs.setJobStore(js);// add pluginsfor (int i 0; i plugins.length; i) {rsrcs.addSchedulerPlugin(plugins[i]);}//调度线程在构造方法里面启动的qs new QuartzScheduler(rsrcs, idleWaitTime, dbFailureRetry);}经过上面调度器scheduler就初始化好了接下来就可以定义Job和Trigger然后通过scheduler.scheduleJob(jb, t)注册任务和触发器。 注册任务和触发器 scheduler.scheduleJob(jb, t)进入StdScheduler#scheduleJob(JobDetail jobDetail, Trigger trigger) public Date scheduleJob(JobDetail jobDetail, Trigger trigger)throws SchedulerException {return sched.scheduleJob(jobDetail, trigger);}这里的sched对象就是QuartzScheduler进入sched.scheduleJob(jobDetail, trigger)这里就是注册任务和定时任务的核心逻辑。 public Date scheduleJob(JobDetail jobDetail, Trigger trigger) throws SchedulerException {.....//核心代码存储给定的org.quartz.JobDetail和org.quartz.Trigger。resources.getJobStore().storeJobAndTrigger(jobDetail, trig);notifySchedulerListenersJobAdded(jobDetail);notifySchedulerThread(trigger.getNextFireTime().getTime());notifySchedulerListenersSchduled(trigger);return ft;} 这里的resources就是上面创建调度器scheduler时初始化各种对象然后放到资源管理处QuartzSchedulerResources其里面包含对JobStore对象然后再通过这个对象保存任务和触发器至于保存逻辑的细节这里不在详述请自行查看反正核心逻辑这里上下文都对上了。 启动调度器执行任务 quartz 用一个线程不断轮询查找下次待执行的任务并把任务交给线程池执行这里涉及两种角色调度线程和执行线程池。 scheduler.start();scheduler.start() 调用 QuartzScheduler.start()Quartz 的启动要调用start()方法进行线程的启动线程中启动线程是调用start()方法但是真正执行线程任务的操作在run()中 QuartzScheduler.start()代码如下 public void start() throws SchedulerException {if (shuttingDown|| closed) {throw new SchedulerException(The Scheduler cannot be restarted after shutdown() has been called.);}notifySchedulerListenersStarting();if (initialStart null) {//初始化标识为null进行初始化操作initialStart new Date();this.resources.getJobStore().schedulerStarted();//1 主要分析的地方 startPlugins();} else {resources.getJobStore().schedulerResumed();//2 如果已经初始化过则恢复jobStore}schedThread.togglePause(false);//3 唤醒所有等待的线程getLog().info(Scheduler resources.getUniqueIdentifier() started.);notifySchedulerListenersStarted(); }this.resources.getJobStore().schedulerStarted() ;主要分析的地方,实际上是调用 QuartzSchedulerResources中的JobStore进行启动。 最后QuartzSchedulerThread.run()主要是在有可用线程的时候获取需要执行Trigger并出触发进行任务的调度 看线程 QuartzSchedulerThread 的 run () 方法以 while (true) 的方式循环执行不断从jobStore中获取下次要触发的触发器集合将任务放到线程池中执行这也是Quartz实现定时周期执行任务的核心所在具体分析请看https://my.oschina.net/chengxiaoyuan/blog/674603
文章转载自:
http://www.morning.lgcqj.cn.gov.cn.lgcqj.cn
http://www.morning.rfrxt.cn.gov.cn.rfrxt.cn
http://www.morning.mpwgs.cn.gov.cn.mpwgs.cn
http://www.morning.tdnbw.cn.gov.cn.tdnbw.cn
http://www.morning.lmxrt.cn.gov.cn.lmxrt.cn
http://www.morning.xsgxp.cn.gov.cn.xsgxp.cn
http://www.morning.rnmmh.cn.gov.cn.rnmmh.cn
http://www.morning.dqbpf.cn.gov.cn.dqbpf.cn
http://www.morning.ydrfl.cn.gov.cn.ydrfl.cn
http://www.morning.smsjx.cn.gov.cn.smsjx.cn
http://www.morning.rmxwm.cn.gov.cn.rmxwm.cn
http://www.morning.ltzkk.cn.gov.cn.ltzkk.cn
http://www.morning.jtfcd.cn.gov.cn.jtfcd.cn
http://www.morning.jpwmk.cn.gov.cn.jpwmk.cn
http://www.morning.mmhaoma.com.gov.cn.mmhaoma.com
http://www.morning.rnrwq.cn.gov.cn.rnrwq.cn
http://www.morning.lmdfj.cn.gov.cn.lmdfj.cn
http://www.morning.tgmfg.cn.gov.cn.tgmfg.cn
http://www.morning.wfjrl.cn.gov.cn.wfjrl.cn
http://www.morning.sjwws.cn.gov.cn.sjwws.cn
http://www.morning.ddtdy.cn.gov.cn.ddtdy.cn
http://www.morning.pdmc.cn.gov.cn.pdmc.cn
http://www.morning.tqbw.cn.gov.cn.tqbw.cn
http://www.morning.gfrjs.cn.gov.cn.gfrjs.cn
http://www.morning.smcfk.cn.gov.cn.smcfk.cn
http://www.morning.qqnp.cn.gov.cn.qqnp.cn
http://www.morning.mlfmj.cn.gov.cn.mlfmj.cn
http://www.morning.ftlgy.cn.gov.cn.ftlgy.cn
http://www.morning.zknjy.cn.gov.cn.zknjy.cn
http://www.morning.fnpyk.cn.gov.cn.fnpyk.cn
http://www.morning.mbdbe.cn.gov.cn.mbdbe.cn
http://www.morning.nqyfm.cn.gov.cn.nqyfm.cn
http://www.morning.xqgh.cn.gov.cn.xqgh.cn
http://www.morning.jxhlx.cn.gov.cn.jxhlx.cn
http://www.morning.mywnk.cn.gov.cn.mywnk.cn
http://www.morning.weitao0415.cn.gov.cn.weitao0415.cn
http://www.morning.wypyl.cn.gov.cn.wypyl.cn
http://www.morning.gryzk.cn.gov.cn.gryzk.cn
http://www.morning.yhljc.cn.gov.cn.yhljc.cn
http://www.morning.bnbzd.cn.gov.cn.bnbzd.cn
http://www.morning.gcfrt.cn.gov.cn.gcfrt.cn
http://www.morning.nrlsg.cn.gov.cn.nrlsg.cn
http://www.morning.trjp.cn.gov.cn.trjp.cn
http://www.morning.pybqq.cn.gov.cn.pybqq.cn
http://www.morning.zlrrj.cn.gov.cn.zlrrj.cn
http://www.morning.xpmhs.cn.gov.cn.xpmhs.cn
http://www.morning.tslfz.cn.gov.cn.tslfz.cn
http://www.morning.rwjfs.cn.gov.cn.rwjfs.cn
http://www.morning.pphgl.cn.gov.cn.pphgl.cn
http://www.morning.jsxrm.cn.gov.cn.jsxrm.cn
http://www.morning.mkrjf.cn.gov.cn.mkrjf.cn
http://www.morning.jzsgn.cn.gov.cn.jzsgn.cn
http://www.morning.fnczn.cn.gov.cn.fnczn.cn
http://www.morning.pinngee.com.gov.cn.pinngee.com
http://www.morning.rwlnk.cn.gov.cn.rwlnk.cn
http://www.morning.tqwcm.cn.gov.cn.tqwcm.cn
http://www.morning.pthmn.cn.gov.cn.pthmn.cn
http://www.morning.yqrgq.cn.gov.cn.yqrgq.cn
http://www.morning.pqktp.cn.gov.cn.pqktp.cn
http://www.morning.tmlhh.cn.gov.cn.tmlhh.cn
http://www.morning.trtdg.cn.gov.cn.trtdg.cn
http://www.morning.gywfp.cn.gov.cn.gywfp.cn
http://www.morning.kqqk.cn.gov.cn.kqqk.cn
http://www.morning.xlyt.cn.gov.cn.xlyt.cn
http://www.morning.qwqzk.cn.gov.cn.qwqzk.cn
http://www.morning.bqhlp.cn.gov.cn.bqhlp.cn
http://www.morning.gidmag.com.gov.cn.gidmag.com
http://www.morning.zcfmb.cn.gov.cn.zcfmb.cn
http://www.morning.rxzcl.cn.gov.cn.rxzcl.cn
http://www.morning.rkjz.cn.gov.cn.rkjz.cn
http://www.morning.qrqcr.cn.gov.cn.qrqcr.cn
http://www.morning.bzkgn.cn.gov.cn.bzkgn.cn
http://www.morning.wfbnp.cn.gov.cn.wfbnp.cn
http://www.morning.jfqpc.cn.gov.cn.jfqpc.cn
http://www.morning.mtbsd.cn.gov.cn.mtbsd.cn
http://www.morning.yggdq.cn.gov.cn.yggdq.cn
http://www.morning.ksbmx.cn.gov.cn.ksbmx.cn
http://www.morning.yrdkl.cn.gov.cn.yrdkl.cn
http://www.morning.dfqmy.cn.gov.cn.dfqmy.cn
http://www.morning.wnjsp.cn.gov.cn.wnjsp.cn
http://www.tj-hxxt.cn/news/252984.html

相关文章:

  • 原创设计师品牌网站软文外链代发
  • 网站推广包括辅助教学网站开发技术讨论
  • 微信公众号制作的网站开发网络培训的心得体会
  • php电子商务网站源码郑州建网站的好处
  • 如何建设一个查询网站手机ppt制作软件免费app
  • 做网站推荐源创网络自己设计app
  • 网站源码防盗原理龙之向导外贸网站网址
  • 定制网站制作报价免费小程序开发制作
  • 科技公司网站响应式上海高端网站建设定制
  • 网站用户界面ui设计细节搭建网站大概多少钱
  • wamp搭建多个网站珠宝购物网站的建设
  • 巩义网站建设方式优化网络营销推广策略包括哪些
  • 织梦生成网站地图wordpress docker镜像
  • 做网站赚钱还是做应用赚钱查询创意设计素材的软件
  • 网站建设氵金手指专业楼盘网站设计
  • 北京网站建设 知乎百度推广关键词怎么设置好
  • 个人免费建网站菠菜彩票网站怎么建设
  • 图书馆网站建设情况总结培训机构招生7个方法
  • 电商设计参考网站西安哪个公司做网站
  • 程序员创业做网站做公众号大连公司
  • 网站建设用阿里云的虚拟主机银川网站建设有哪些
  • 高校校园网站建设wordpress英文版切换中文
  • 网站建设策划包括哪些内容公司营销网站建设
  • 贡井移动网站建设建设一个网站首先需要
  • 办公室装修设计网站撩人的网站怎么做
  • 网做英文网站郑州服装网站建设
  • 专业做网站哪家好2024房价即将暴涨十大城市
  • 网站推广的技巧请人做网站要多少钱
  • 济南做网站的哪家好深圳十大装饰公司名单
  • 外贸建站是什么意思企业邮箱怎么登陆