大并发大数据量请求一般会分为几种情况:
大量的用户同时对系统的不同功能页面进行查找、更新操作
大量的用户同时对系统的同一个页面,同一个表的大数据量进行查询操作
大量的用户同时对系统的同一个页面,同一个表进行更新操作
构建主题时,将使用模板文件来影响网站不同部分的布局和设计。例如,您将使用header.php模板创建页眉,或使用comments.php模板引入评论。
当有人访问您网站上的页面时,WordPress会根据请求来加载模板。模板文件显示的内容类型由模板文件关联的文章类型确定。模板层次描述了WordPress 将根据请求的类型加载哪个模板文件,以及模板是否存在于主题中。 然后,服务器解析模板中的PHP,并将HTML返回给访问者。
最关键的模板文件是index.php,如果在模板层次结构中找不到更具体的模板,那么所有请求最终都会被发送到这个模板上 。尽管主题仅需要一个 index.php模板,但通常主题包含许多模板,以便在不同的上下文中环境中显示不同的内容 。
View Detailshttps://news.51cto.com/art/202103/652739.htm首先,你需要复制以下内容:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# GitHub520 Host Start 185.199.108.154 github.githubassets.com 140.82.114.21 central.github.com 185.199.108.133 desktop.githubusercontent.com 185.199.108.153 assets-cdn.github.com 185.199.108.133 camo.githubusercontent.com 185.199.108.133 github.map.fastly.net 199.232.69.194 github.global.ssl.fastly.net 140.82.113.4 gist.github.com 185.199.108.153 github.io 140.82.114.3 github.com 140.82.113.5 api.github.com 185.199.108.133 raw.githubusercontent.com 185.199.108.133 user-images.githubusercontent.com 185.199.108.133 favicons.githubusercontent.com 185.199.108.133 avatars5.githubusercontent.com 185.199.108.133 avatars4.githubusercontent.com 185.199.108.133 avatars3.githubusercontent.com 185.199.108.133 avatars2.githubusercontent.com 185.199.108.133 avatars1.githubusercontent.com 185.199.108.133 avatars0.githubusercontent.com 185.199.108.133 avatars.githubusercontent.com 140.82.113.10 codeload.github.com 52.216.226.40 github-cloud.s3.amazonaws.com 52.216.162.99 github-com.s3.amazonaws.com 52.216.142.196 github-production-release-asset-2e65be.s3.amazonaws.com 52.217.97.236 github-production-user-asset-6210df.s3.amazonaws.com 52.217.194.41 github-production-repository-file-5c1aeb.s3.amazonaws.com 185.199.108.153 githubstatus.com 64.71.168.201 github.community 185.199.108.133 media.githubusercontent.com # Update time: 2021-03-24T16:06:33+08:00 # Star me GitHub url: https://github.com/521xueweihan/GitHub520 # GitHub520 Host End |
接着,你需要去修改 hosts 文件,hosts 文件在每个系统的位置不一,详情如下: Windows 系统:C:\Windows\System32\drivers\etc\hosts Linux 系统:/etc/hosts Mac(苹果电脑)系统:/etc/hosts Android(安卓)系统:/system/etc/hosts iPhone(iOS)系统:/etc/hosts 修改方法,把第一步的内容复制到文本末尾: Windows 使用记事本。 Linux、Mac 使用 Root 权限:sudo vi /etc/hosts。 iPhone、iPad 须越狱、Android 必须要 root。 大部分情况下是直接生效,如未生效可尝试下面的办法,刷新 DNS: Windows:在 CMD 窗口输入:ipconfig /flushdns Linux 命令:sudo rcnscd restart Mac 命令:sudo killall -HUP mDNSResponder 是不是觉得超级简单?目前,GitHub520已经在Github上标星 4.1K,累计分支 348 个(Github地址:https://github.com/521xueweihan/GitHub520) 如果你的Github在访问时也出现图裂、或者加载缓慢等问题,不妨试试。Github520,让你重新爱上Github。 from:https://www.cnblogs.com/rxbook/p/15241501.html
View DetailsWordPress首页默认显示的是每篇文章的全部内容 ,发表文章的时候在首页面预览会显示文章的全部内容,很影响我们的阅读体验. 在wp-content\themes目录下,选择你自己安装模板,然后打开index.php,你会发现部分代码如下:
|
1 2 3 4 5 6 7 |
while ( have_posts() ) { the_post(); get_template_part( 'xxx', get_post_format() ); } |
index.php是调用xxx.php的文件用来输出文章的内容,你在模板目录下找到xxx.php,打开编辑它,找到这段代码:
|
1 |
the_content( __( 'Read more...', 'xxx' ) ); |
将该行代码注释掉,修改成:
|
1 2 3 4 5 6 7 8 9 |
if(!is_single()) { the_excerpt(); } else { the_content(__('(more…)')); } |
from:https://www.cnblogs.com/lionli/p/11944963.html
View Details在ASP.NET Core 3.0中路由配置和2.0不一样了 一、MVC 服务注册 ASP.NET Core 3.0 添加了用于注册内部的 MVC 方案的新选项Startup.ConfigureServices。 三个新的顶级扩展方法与 MVC 方案上IServiceCollection可用。 模板使用这些新方法,而不是UseMvc。 但是,AddMvc继续像它已在以前的版本。 下面的示例将添加对控制器和与 API 相关的功能,但不是视图或页面的支持。 API 模板使用此代码:
|
1 2 3 4 |
public void ConfigureServices(IServiceCollection services) { services.AddControllers(); } |
下面的示例将添加对控制器、 与 API 相关的功能,和视图,但不是页面的支持。 Web 应用程序 (MVC) 模板使用此代码:
|
1 2 3 4 |
public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews(); } |
下面的示例添加支持 Razor 页面和最小控制器支持。 Web 应用程序模板使用此代码:
|
1 2 3 4 |
public void ConfigureServices(IServiceCollection services) { services.AddRazorPages(); } |
此外可以组合的新方法。 下面的示例是等效于调用AddMvcASP.NET Core 2.2 中:
|
1 2 3 4 5 |
public void ConfigureServices(IServiceCollection services) { services.AddControllers(); services.AddRazorPages(); } |
二、Startup.Configure配置 一般不建议: 添加UseRouting。 如果该应用程序调用UseStaticFiles,将置于UseStaticFiles之前 UseRouting。 如果应用使用身份验证/授权功能,如AuthorizePage或[Authorize],将对UseAuthentication并UseAuthorization后 UseRouting。 如果应用使用CORS功能,如[EnableCors],将放置UseCors下一步。 替换UseMvc或UseSignalR与UseEndpoints。 以下是一种Startup.Configure典型的 ASP.NET Core 2.2 应用中:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
public void Configure(IApplicationBuilder app) { ... app.UseStaticFiles(); app.UseAuthentication(); app.UseSignalR(hubs => { hubs.MapHub<ChatHub>("/chat"); }); app.UseMvc(routes => { routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}"); }); } |
现在的控制器映射内发生UseEndpoints。 添加MapControllers如果应用使用属性路由。 由于路由包括对许多框架在 ASP.NET Core 3.0 或更高版本的支持,添加属性路由的控制器是参加。 将为以下内容: MapRoute 使用 MapControllerRoute MapAreaRoute 使用 MapAreaControllerRoute 由于路由现在包括对不止是 MVC 的支持,已更改了术语进行明确说明他们所做的这些方法。 如传统路由MapControllerRoute / MapAreaControllerRoute / MapDefaultControllerRoute它们要添加的顺序应用。 将第一位更具体的路由 (如某一区域的路由)。 如下示例中: […]
View Details不能为虚拟电脑 CentOS7a 打开一个新任务. Call to NEMR0InitVMPart2 failed: VERR_NEM_INIT_FAILED (VERR_NEM_VM_CREATE_FAILED).
|
1 2 3 |
返回 代码: E_FAIL (0x80004005) 组件: ConsoleWrap 界面: IConsole {872da645-4a9b-1727-bee2-5585105b9eed} |
解决方案:禁用Hyper-V 以管理员身份运行cmd输入
|
1 |
bcdedit /set hypervisorlaunchtype off |
重启电脑 ———————————————— 版权声明:本文为CSDN博主「1home」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/weixin_45673166/article/details/120982710
View Detailsdocker logs -f -t --since="2017-05-31" --tail=10 edu_web_1 --since : 此参数指定了输出日志开始日期,即只输出指定日期之后的日志。 -f : 查看实时日志 -t : 查看日志产生的日期 -tail=10 : 查看最后的10条日志。 edu_web_1 : 容器名称 from:https://www.cnblogs.com/qufanblog/p/6927411.html
View DetailsDocker从1.13版本之后采用时间线的方式作为版本号,分为社区版CE和企业版EE。
社区版是免费提供给个人开发者和小型团体使用的,企业版会提供额外的收费服务,比如经过官方测试认证过的基础设施、容器、插件等。
社区版按照stable和edge两种方式发布,每个季度更新stable版本,如17.06,17.09;每个月份更新edge版本,如17.09,17.10。
在电商、支付等领域,往往会有这样的场景,用户下单后放弃支付了,那这笔订单会在指定的时间段后进行关闭操作,细心的你一定发现了像某宝、某东都有这样的逻辑,而且时间很准确,误差在1s内;那他们是怎么实现的呢? 一般的做法有如下几种 定时任务关闭订单 rocketmq延迟队列 rabbitmq死信队列 时间轮算法 redis过期监听 一、定时任务关闭订单(最low) 一般情况下,最不推荐的方式就是关单方式就是定时任务方式,原因我们可以看下面的图来说明 我们假设,关单时间为下单后10分钟,定时任务间隔也是10分钟;通过上图我们看出,如果在第1分钟下单,在第20分钟的时候才能被扫描到执行关单操作,这样误差达到10分钟,这在很多场景下是不可接受的,另外需要频繁扫描主订单号造成网络IO和磁盘IO的消耗,对实时交易造成一定的冲击,所以PASS 二、rocketmq延迟队列方式 延迟消息 生产者把消息发送到消息服务器后,并不希望被立即消费,而是等待指定时间后才可以被消费者消费,这类消息通常被称为延迟消息。 在RocketMQ开源版本中,支持延迟消息,但是不支持任意时间精度的延迟消息,只支持特定级别的延迟消息。 消息延迟级别分别为1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h,共18个级别。 发送延迟消息(生产者)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
/** * 推送延迟消息 * @param topic * @param body * @param producerGroup * @return boolean */ public boolean sendMessage(String topic, String body, String producerGroup) { try { Message recordMsg = new Message(topic, body.getBytes()); producer.setProducerGroup(producerGroup); //设置消息延迟级别,我这里设置14,对应就是延时10分钟 // "1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h" recordMsg.setDelayTimeLevel(14); // 发送消息到一个Broker SendResult sendResult = producer.send(recordMsg); // 通过sendResult返回消息是否成功送达 log.info("发送延迟消息结果:======sendResult:{}", sendResult); DateFormat format =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); log.info("发送时间:{}", format.format(new Date())); return true; } catch (Exception e) { e.printStackTrace(); log.error("延迟消息队列推送消息异常:{},推送内容:{}", e.getMessage(), body); } return false; } |
消费延迟消息(消费者)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
/** * 接收延迟消息 * * @param topic * @param consumerGroup * @param messageHandler */ public void messageListener(String topic, String consumerGroup, MessageListenerConcurrently messageHandler) { ThreadPoolUtil.execute(() -> { try { DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(); consumer.setConsumerGroup(consumerGroup); consumer.setVipChannelEnabled(false); consumer.setNamesrvAddr(address); //设置消费者拉取消息的策略,*表示消费该topic下的所有消息,也可以指定tag进行消息过滤 consumer.subscribe(topic, "*"); //消费者端启动消息监听,一旦生产者发送消息被监听到,就打印消息,和rabbitmq中的handlerDelivery类似 consumer.registerMessageListener(messageHandler); consumer.start(); log.info("启动延迟消息队列监听成功:" + topic); } catch (MQClientException e) { log.error("启动延迟消息队列监听失败:{}", e.getErrorMessage()); System.exit(1); } }); } |
实现监听类,处理具体逻辑
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
/** * 延迟消息监听 * */ @Component public class CourseOrderTimeoutListener implements ApplicationListener<ApplicationReadyEvent> { @Resource private MQUtil mqUtil; @Resource private CourseOrderTimeoutHandler courseOrderTimeoutHandler; @Override public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) { // 订单超时监听 mqUtil.messageListener(EnumTopic.ORDER_TIMEOUT, EnumGroup.ORDER_TIMEOUT_GROUP, courseOrderTimeoutHandler); } } |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
/** * 实现监听 */ @Slf4j @Component public class CourseOrderTimeoutHandler implements MessageListenerConcurrently { @Override public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> list, ConsumeConcurrentlyContext consumeConcurrentlyContext) { for (MessageExt msg : list) { // 得到消息体 String body = new String(msg.getBody()); JSONObject userJson = JSONObject.parseObject(body); TCourseBuy courseBuyDetails = JSON.toJavaObject(userJson, TCourseBuy.class); // 处理具体的业务逻辑,,,,, DateFormat format =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); log.info("消费时间:{}", format.format(new Date())); return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; } } |
这种方式相比定时任务好了很多,但是有一个致命的缺点,就是延迟等级只有18种(商业版本支持自定义时间),如果我们想把关闭订单时间设置在15分钟该如何处理呢?显然不够灵活。 三、rabbitmq死信队列的方式 Rabbitmq本身是没有延迟队列的,只能通过Rabbitmq本身队列的特性来实现,想要Rabbitmq实现延迟队列,需要使用Rabbitmq的死信交换机(Exchange)和消息的存活时间TTL(Time To Live) 死信交换机 一个消息在满足如下条件下,会进死信交换机,记住这里是交换机而不是队列,一个交换机可以对应很多队列。 一个消息被Consumer拒收了,并且reject方法的参数里requeue是false。也就是说不会被再次放在队列里,被其他消费者使用。 上面的消息的TTL到了,消息过期了。 队列的长度限制满了。排在前面的消息会被丢弃或者扔到死信路由上。 死信交换机就是普通的交换机,只是因为我们把过期的消息扔进去,所以叫死信交换机,并不是说死信交换机是某种特定的交换机 消息TTL(消息存活时间) 消息的TTL就是消息的存活时间。RabbitMQ可以对队列和消息分别设置TTL。对队列设置就是队列没有消费者连着的保留时间,也可以对每一个单独的消息做单独的设置。超过了这个时间,我们认为这个消息就死了,称之为死信。如果队列设置了,消息也设置了,那么会取值较小的。所以一个消息如果被路由到不同的队列中,这个消息死亡的时间有可能不一样(不同的队列设置)。这里单讲单个消息的TTL,因为它才是实现延迟任务的关键。
|
1 2 3 4 |
byte[] messageBodyBytes = "Hello, world!".getBytes(); AMQP.BasicProperties properties = new AMQP.BasicProperties(); properties.setExpiration("60000"); channel.basicPublish("my-exchange", "queue-key", properties, messageBodyBytes); |
可以通过设置消息的expiration字段或者x-message-ttl属性来设置时间,两者是一样的效果。只是expiration字段是字符串参数,所以要写个int类型的字符串:当上面的消息扔到队列中后,过了60秒,如果没有被消费,它就死了。不会被消费者消费到。这个消息后面的,没有“死掉”的消息对顶上来,被消费者消费。死信在队列中并不会被删除和释放,它会被统计到队列的消息数中去 处理流程图 创建交换机(Exchanges)和队列(Queues) 创建死信交换机 如图所示,就是创建一个普通的交换机,这里为了方便区分,把交换机的名字取为:delay 创建自动过期消息队列 这个队列的主要作用是让消息定时过期的,比如我们需要2小时候关闭订单,我们就需要把消息放进这个队列里面,把消息过期时间设置为2小时 创建一个一个名为delay_queue1的自动过期的队列,当然图片上面的参数并不会让消息自动过期,因为我们并没有设置x-message-ttl参数,如果整个队列的消息有消息都是相同的,可以设置,这里为了灵活,所以并没有设置,另外两个参数x-dead-letter-exchange代表消息过期后,消息要进入的交换机,这里配置的是delay,也就是死信交换机,x-dead-letter-routing-key是配置消息过期后,进入死信交换机的routing-key,跟发送消息的routing-key一个道理,根据这个key将消息放入不同的队列 创建消息处理队列 这个队列才是真正处理消息的队列,所有进入这个队列的消息都会被处理 消息队列的名字为delay_queue2 消息队列绑定到交换机 进入交换机详情页面,将创建的2个队列(delayqueue1和delayqueue2)绑定到交换机上面 自动过期消息队列的routing key 设置为delay 绑定delayqueue2 delayqueue2 的key要设置为创建自动过期的队列的x-dead-letter-routing-key参数,这样当消息过期的时候就可以自动把消息放入delay_queue2这个队列中了 绑定后的管理页面如下图: 当然这个绑定也可以使用代码来实现,只是为了直观表现,所以本文使用的管理平台来操作 发送消息
|
1 2 3 4 5 6 |
String msg = "hello word"; MessageProperties messageProperties = newMessageProperties(); messageProperties.setExpiration("6000"); messageProperties.setCorrelationId(UUID.randomUUID().toString().getBytes()); Message message = newMessage(msg.getBytes(), messageProperties); rabbitTemplate.convertAndSend("delay", "delay",message); |
设置了让消息6秒后过期 注意:因为要让消息自动过期,所以一定不能设置delay_queue1的监听,不能让这个队列里面的消息被接受到,否则消息一旦被消费,就不存在过期了 接收消息 接收消息配置好delay_queue2的监听就好了
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
package wang.raye.rabbitmq.demo1; import org.springframework.amqp.core.AcknowledgeMode; import org.springframework.amqp.core.Binding; import org.springframework.amqp.core.BindingBuilder; import org.springframework.amqp.core.DirectExchange; import org.springframework.amqp.core.Message; import org.springframework.amqp.core.Queue; import org.springframework.amqp.rabbit.connection.CachingConnectionFactory; import org.springframework.amqp.rabbit.connection.ConnectionFactory; import org.springframework.amqp.rabbit.core.ChannelAwareMessageListener; import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration publicclassDelayQueue{ /** 消息交换机的名字*/ publicstaticfinalString EXCHANGE = "delay"; /** 队列key1*/ publicstaticfinalString ROUTINGKEY1 = "delay"; /** 队列key2*/ publicstaticfinalString ROUTINGKEY2 = "delay_key"; /** * 配置链接信息 * @return */ @Bean publicConnectionFactory connectionFactory() { CachingConnectionFactory connectionFactory = newCachingConnectionFactory("120.76.237.8",5672); connectionFactory.setUsername("kberp"); connectionFactory.setPassword("kberp"); connectionFactory.setVirtualHost("/"); connectionFactory.setPublisherConfirms(true); // 必须要设置 return connectionFactory; } /** * 配置消息交换机 * 针对消费者配置 FanoutExchange: 将消息分发到所有的绑定队列,无routingkey的概念 HeadersExchange :通过添加属性key-value匹配 DirectExchange:按照routingkey分发到指定队列 TopicExchange:多关键字匹配 */ @Bean publicDirectExchange defaultExchange() { returnnewDirectExchange(EXCHANGE, true, false); } /** * 配置消息队列2 * 针对消费者配置 * @return */ @Bean publicQueue queue() { returnnewQueue("delay_queue2", true); //队列持久 } /** * 将消息队列2与交换机绑定 * 针对消费者配置 * @return */ @Bean @Autowired publicBinding binding() { returnBindingBuilder.bind(queue()).to(defaultExchange()).with(DelayQueue.ROUTINGKEY2); } /** * 接受消息的监听,这个监听会接受消息队列1的消息 * 针对消费者配置 * @return */ @Bean @Autowired publicSimpleMessageListenerContainer messageContainer2(ConnectionFactory connectionFactory) { SimpleMessageListenerContainer container = newSimpleMessageListenerContainer(connectionFactory()); container.setQueues(queue()); container.setExposeListenerChannel(true); container.setMaxConcurrentConsumers(1); container.setConcurrentConsumers(1); container.setAcknowledgeMode(AcknowledgeMode.MANUAL); //设置确认模式手工确认 container.setMessageListener(newChannelAwareMessageListener() { publicvoid onMessage(Message message, com.rabbitmq.client.Channel channel) throwsException{ byte[] body = message.getBody(); System.out.println("delay_queue2 收到消息 : "+ newString(body)); channel.basicAck(message.getMessageProperties().getDeliveryTag(), false); //确认消息成功消费 } }); return container; } } |
[…]
View Details