喜欢的少年是你

喜欢的少年是你 查看完整档案

填写现居城市攀枝花学院  |  软件工程 编辑  |  填写所在公司/组织 feicheng.xyz/ 编辑
编辑
_ | |__ _ _ __ _ | '_ \| | | |/ _` | | |_) | |_| | (_| | |_.__/ \__,_|\__, | |___/ 该用户太懒什么也没留下

个人动态

喜欢的少年是你 发布了文章 · 9月26日

RabbitMQ实战二(消峰限流)

Hello,我是一名在互联网捡破烂的程序员,最近破烂还挺好捡的,每天都是东逛逛西逛逛,收了很多的破烂呢。。。

收废铁了,十块一斤。快拿来卖哦,什么烂电冰箱,烂电视机,不管什么破烂我都要。。。

每天骑着我的烂三轮车,每天都是活的苟且偷生的,我好可怜。。。

呜呜呜呜

不管有钱木钱,都进来看一看瞧一瞧哦。。

好了~~~~

废话我们就不多说了,我最近在收废铁的时候收到一本武功秘籍,发现了新大陆,今天我就来和你们分享一下。

我们一起成为武林霸主,来吧。氛围搞起来。。。。。

首先呢,我们在上一期中对 RabbitMQ做了一个小小的实践,主要是对 RabbitMQ的异步特性进行了分析。

如果小伙伴还没有修炼的,赶紧去修炼去吧,我们要慢慢的成长起来,要慢慢的修炼武功秘籍,不是一天两天就可以练成的,让我们一起成为世界的主宰吧,嗯哈哈哈哈哈

RabbitMQ实践一(异步解耦)

如果你还是一个一个刚刚入门的小伙伴呢,那你的加紧你的步伐,赶快去从武功秘籍的第一页开始吧,你也不要慌张,我们都是从小白开始的,只不过你要多花一点时间来完成前面的修炼,终有一天你会超过的,哈哈哈
RabbitMQ基本使用一(简单介绍)/#more)

RabbitMQ基本使用二(简单队列)

RabbitMQ基本使用三(工作队列)

RabbitMQ基本使用四(发布/订阅模式)

RabbitMQ基本使用五(路由模式)

RabbitMQ基本使用六(主题模式)

RabbitMQ入门呢?就是上面的这么多啦。自己根据官网来理解的知识点,写的不是那么很好,不过很通俗易懂。代码有详细介绍。如有问题,请留言,多多包涵。

好吧,我们就废话不多说了,那就开始我们的表演吧!!!!

一、开篇前提

本文篇幅比较长,请耐心阅读,你会收获很多的。

今天给大家带来的是 RabbitMQ的消峰限流,我们知道现在互联网越来越强大,我们的系统也是越来越完善,在高峰期呢,系统将要承受巨大的压力,那么也是我们程序员的压力。像淘宝、京东大型网站购物系统每逢双十一,那就是程序员最忙的时候,当天要承受千万级别的流量冲击,不得不抵住压力啊。

想必大家都知道哦我要说什么了吧,没错,就是你想的那样,我们就是要对这千万级别的流量打交道。我们要抵住流量的冲击。让它能够缓解我们的系统的压力,系统压力小了,我们自身的压力就小了。OK

1. 场景介绍

  • 场景一

    我们知道在我们双十一中都会有秒杀的商品,我们所秒杀的商品价格都是非常低的,并且商品也是非常好,比如华为Mate30只要999,、苹果12只要99等等这些秒杀商品,不管是谁,看了都会心动。但是呢,商品的数量是有限的,不是每个用户都会抢到,全国14亿用户,就拿一半的人来抢,那个流量冲击是我们无法想像的。那要是全部流量打在我们的数据库中,那就只有说再见。。凉凉,最后还是我们程序员扛下了所有,那么我们应该怎么办呢?

  • 场景二

相信大多数人都抢过火车票吧,肯定有没有抢到票的吧。比如在我们的12306抢票网站,每次到一定的时间段都会有大量用户涌入抢票,可能我会遇到过服务器忙、或者加载失败等情况。那么在这么大的流量下,我们是怎么抗住的呢?

2. 问题描述

在我们面对瞬时流量的情况下,全部的流量都打在我们的数据库中,那是很难受的。

那么我们应该怎么来解决这种瞬时流量下的并发情况?

在我们秒杀中,库存只有一份,所有人会集中在时间读和写写这些数据,多人读取同一个数据

3. 优化方案

我们无论在抢票或者秒杀商品中时,为什么我没有抢到,别人却抢到了?

下面带你打开这扇门

  • 我们将请求尽量拦截在系统的上游(不要让锁冲突到数据上)。为什么那些传统的秒杀系统会挂,那是因为所有的请求都压到了数据层上,导致数据读取锁冲突,并发的响应数据慢,巨几乎都是所有请求超时。流量虽大,下单成功的有效流量去很少。如果我们秒杀商品库存有100件,那么有1000W人来抢,那么那时的瞬时流量很大,但是基本没有人秒杀成功,原因在于所有的流浪都打在我们的数据层上,到时响应速度慢,请求的有效率为0。那么这是一次很失败的秒杀活动。

    那用户不得吐槽啊,还不得上热搜啊,某某什么秒杀系统,垃圾的很,没人秒杀成功,都是请求超时,哎,溜了溜了

    那程序员就遭殃了啊,老板还不得直接暴扣到头上啊,那是很难受的,薪水都要大打折扣。

  • 充分利用缓存来实现这种瞬时流量大的情况,秒杀买票,这就是一个典型的读多写少的应用场景,大部分请求是车次的查询,票查询,下单和支付才是写请求。一趟火车其实只有2000张票,200W人来买,最多只有2000人下单成功,其他人都是查询库存,写比例只有0.1%,读的比例占99.9%,非常适合用缓存来优化。

这下知道为什么有时候抢不到商品了吧

这样的设计就是为了牺牲用户流量来换系统稳定

4. 架构

image
这个架构我是根据自己的理解来的,可能不怎么符合理念,知道大概意思就是了哈

OK,说了这么多,我们就开始我们的代码设计吧

二、实践操作

1. 项目开始阶段

下面的所有代码都是本人独立完成,可能不是那么完美,不过应该问题不大吧

如有错误之处,还请包涵,多多指出

这里我们加入我们的 Redis缓存技术,有时间会更新的。。

首先我们要有 RabbitMQ的客户端,可以在Linux上安装,也可以在Windows上安装。

我使用的是Linux上安装的,可以去参考 RabbitMQ在Linux下安装

1.1 创建SpringBoot项目

这个就不用多说了吧,这个都是我们的家常便饭了

1.2 导入依赖
 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
            <version>2.2.4.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.1</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

主要是导入我们我们的 MQ依赖

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
            <version>2.2.4.RELEASE</version>
        </dependency>
1.3 修改application.yml
server:
  port: 9000
spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/test_rabbitmq?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
    username: root
    password: root
  rabbitmq:
    addresses: 192.168.2.2
    virtual-host: /
    username: guest
    password: guest
    template:
      exchange: ORDER.EXCHANGE
    listener:
     simple:
       #指定最小的消费者数量
       concurrency: 1
       retry:
         enabled: false #是否支持重试
       prefetch: 100
       acknowledge-mode: manual
logging:
  level:
    com.example.rabbitmq.mapper: debug
mybatis:
  mapper-locations: classpath:mapper/*.xml

主要配置的说明

1.3 数据库连接
spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/test_rabbitmq?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
    username: root
    password: root

将用户名和密码修改为自己的

如果你的数据库是在Linux上,那么你需要将localhost修改为你的IP地址,并开启3306端口

1.4 RabbitMQ基本配置
  • 基本配置
 rabbitmq:
    addresses: 192.168.2.2
    virtual-host: /
    username: guest
    password: guest

注意,我这里没有列出格式

rabbitmq这是是在spring下的

address:这个是你的IP地址,同样的如果你的 RabbitMQ是在Linux上,使用Linux的IP地址。若是windows版本,直接使用localhost

virtual-host:这个是你rabbitmq上的一个虚拟主机

username:用户名,如果你没有添加用户:默认的是guest

password:密码,同样,如果你没有添加用户:默认是guest

具体说明请详见 RabbitMQ在Linux下安装

  • 默认交换机
 template:
      exchange: ORDER.EXCHANGE

这里我们可以定义默认的交换机名称,那么在代码中我们就需要设置这样的名称

  • 消费者监听配置
listener:
     simple:
       #指定最小的消费者数量
       concurrency: 1
       retry:
         enabled: false #是否支持重试
       prefetch: 100 #每次处理的消息
       acknowledge-mode: manual #手动确认

上面的注释已经很清楚明白了吧,具体需要配置自己可以自行配置。

1.5 日志打印配置(主要打印我们的SQL语句)
logging:
  level:
    com.example.rabbitmq.mapper: debug
1.6 mybatis配置文件位置
mybatis:
  mapper-locations: classpath:mapper/*.xml

2. 数据库(test_rabbitmq)

2.1 Order(订单表)
DROP TABLE IF EXISTS `test_order`;

CREATE TABLE `test_order` (
  `order_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '订单Id',
  `order_user_name` varchar(255) DEFAULT NULL COMMENT '订单人的名称',
  `order_user_email` varchar(255) DEFAULT NULL COMMENT '订单人的邮箱',
  `order_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '订单时间',
  PRIMARY KEY (`order_id`)
) ENGINE=InnoDB AUTO_INCREMEN
2.2 Googs(商品表)
DROP TABLE IF EXISTS `test_goods`;

CREATE TABLE `test_goods` (
  `goods_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '商品Id',
  `goods_name` varchar(255) DEFAULT NULL COMMENT '商品名称',
  `goods_stock` int(100) DEFAULT NULL COMMENT '商品库存',
  PRIMARY KEY (`goods_id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
insert  into `test_goods`(`goods_id`,`goods_name`,`goods_stock`) values (1,'商品',0);
查看原文

赞 0 收藏 0 评论 0

喜欢的少年是你 关注了用户 · 9月25日

敖丙 @aobing

关注 3787

喜欢的少年是你 关注了标签 · 9月25日

java

Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的 Java 程序设计语言和 Java 平台(即 JavaSE, JavaEE, JavaME)的总称。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

Java编程语言的风格十分接近 C++ 语言。继承了 C++ 语言面向对象技术的核心,Java舍弃了 C++ 语言中容易引起错误的指針,改以引用取代,同时卸载原 C++ 与原来运算符重载,也卸载多重继承特性,改用接口取代,增加垃圾回收器功能。在 Java SE 1.5 版本中引入了泛型编程、类型安全的枚举、不定长参数和自动装/拆箱特性。太阳微系统对 Java 语言的解释是:“Java编程语言是个简单、面向对象、分布式、解释性、健壮、安全与系统无关、可移植、高性能、多线程和动态的语言”。

版本历史

重要版本号版本代号发布日期
JDK 1.01996 年 1 月 23 日
JDK 1.11997 年 2 月 19 日
J2SE 1.2Playground1998 年 12 月 8 日
J2SE 1.3Kestrel2000 年 5 月 8 日
J2SE 1.4Merlin2002 年 2 月 6 日
J2SE 5.0 (1.5.0)Tiger2004 年 9 月 30 日
Java SE 6Mustang2006 年 11 月 11 日
Java SE 7Dolphin2011 年 7 月 28 日
Java SE 8JSR 3372014 年 3 月 18 日
最新发布的稳定版本:
Java Standard Edition 8 Update 11 (1.8.0_11) - (July 15, 2014)
Java Standard Edition 7 Update 65 (1.7.0_65) - (July 15, 2014)

更详细的版本更新查看 J2SE Code NamesJava version history 维基页面

新手帮助

不知道如何开始写你的第一个 Java 程序?查看 Oracle 的 Java 上手文档

在你遇到问题提问之前,可以先在站内搜索一下关键词,看是否已经存在你想提问的内容。

命名规范

Java 程序应遵循以下的 命名规则,以增加可读性,同时降低偶然误差的概率。遵循这些命名规范,可以让别人更容易理解你的代码。

  • 类型名(类,接口,枚举等)应以大写字母开始,同时大写化后续每个单词的首字母。例如:StringThreadLocaland NullPointerException。这就是著名的帕斯卡命名法。
  • 方法名 应该是驼峰式,即以小写字母开头,同时大写化后续每个单词的首字母。例如:indexOfprintStackTraceinterrupt
  • 字段名 同样是驼峰式,和方法名一样。
  • 常量表达式的名称static final 不可变对象)应该全大写,同时用下划线分隔每个单词。例如:YELLOWDO_NOTHING_ON_CLOSE。这个规范也适用于一个枚举类的值。然而,static final 引用的非不可变对象应该是驼峰式。

Hello World

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}

编译并调用:

javac -d . HelloWorld.java
java -cp . HelloWorld

Java 的源代码会被编译成可被 Java 命令执行的中间形式(用于 Java 虚拟机的字节代码指令)。

可用的 IDE

学习资源

常见的问题

下面是一些 SegmentFault 上在 Java 方面经常被人问到的问题:

(待补充)

关注 104563

喜欢的少年是你 关注了标签 · 9月25日

前端

Web前端开发是从网页制作演变而来的,名称上有很明显的时代特征。在互联网的演化进程中,网页制作是Web 1.0时代的产物,那时网站的主要内容都是静态的,用户使用网站的行为也以浏览为主。2005年以后,互联网进入Web 2.0时代,各种类似桌面软件的Web应用大量涌现,网站的前端由此发生了翻天覆地的变化。网页不再只是承载单一的文字和图片,各种富媒体让网页的内容更加生动,网页上软件化的交互形式为用户提供了更好的使用体验,这些都是基于前端技术实现的。

Web前端优化
  1. 尽量减少HTTP请求 (Make Fewer HTTP Requests)
  2. 减少 DNS 查找 (Reduce DNS Lookups)
  3. 避免重定向 (Avoid Redirects)
  4. 使得 Ajax 可缓存 (Make Ajax Cacheable)
  5. 延迟载入组件 (Post-load Components)
  6. 预载入组件 (Preload Components)
  7. 减少 DOM 元素数量 (Reduce the Number of DOM Elements)
  8. 切分组件到多个域 (Split Components Across Domains)
  9. 最小化 iframe 的数量 (Minimize the Number of iframes)
  10. 杜绝 http 404 错误 (No 404s)

关注 151983

喜欢的少年是你 关注了标签 · 9月25日

关注 81344

喜欢的少年是你 关注了标签 · 9月25日

linux

Linux是一种自由和开放源代码的类Unix计算机操作系统。目前存在着许多不同的Linux,但它们全都使用了Linux内核。Linux可安装在各种各样的计算机硬件设备,从手机、平板电脑、路由器和视频游戏控制台,到台式计算机,大型机和超级计算机。

Linux家族家谱图,很全很强大!! 图中可以清楚的看出各个Linux发行版的血缘关系。无水印原图:http://url.cn/5ONhQb

关注 63564

喜欢的少年是你 关注了标签 · 9月25日

程序员

一种近几十年来出现的新物种,是工业革命的产物。英文(Programmer Monkey)是一种非常特殊的、可以从事程序开发、维护的动物。一般分为程序设计猿和程序编码猿,但两者的界限并不非常清楚,都可以进行开发、维护工作,特别是在中国,而且最重要的一点,二者都是一种非常悲剧的存在。

国外的程序员节

国外的程序员节,(英语:Programmer Day,俄语:День программи́ста)是一个俄罗斯官方节日,日期是每年的第 256(0x100) 天,也就是平年的 9 月 13 日和闰年的 9 月 12 日,选择 256 是因为它是 2 的 8 次方,比 365 少的 2 的最大幂。

1024程序员节,中国程序员节

1024是2的十次方,二进制计数的基本计量单位之一。程序员(英文Programmer)是从事程序开发、维护的专业人员。程序员就像是一个个1024,以最低调、踏实、核心的功能模块搭建起这个科技世界。1GB=1024M,而1GB与1级谐音,也有一级棒的意思。

从2012年,SegmentFault 创办开始我们就从网络上引导社区的开发者,发展成中国程序员的节日 :) 计划以后每年10月24日定义为程序员节。以一个节日的形式,向通过Coding 改变世界,也以实际行动在浮躁的世界里,固执地坚持自己对于知识、技术和创新追求的程序员们表示致敬。并于之后的最为临近的周末为程序员们举行了一个盛大的狂欢派对。

2015的10月24日,我们SegmentFault 也在5个城市同时举办黑客马拉松这个特殊的形式,聚集开发者开一个编程大爬梯。

特别推荐:

【SF 黑客马拉松】:http://segmentfault.com/hacka...
【1024程序员闯关秀】小游戏,欢迎来挑战 http://segmentfault.com/game/

  • SF 开发者交流群:206236214
  • 黑客马拉松交流群:280915731
  • 开源硬件交流群:372308136
  • Android 开发者交流群:207895295
  • iOS 开发者交流群:372279630
  • 前端开发者群:174851511

欢迎开发者加入~

交流群信息


程序员相关问题集锦:

  1. 《程序员如何选择自己的第二语言》
  2. 《如何成为一名专业的程序员?》
  3. 《如何用各种编程语言书写hello world》
  4. 《程序员们最常说的谎话是什么?》
  5. 《怎么加入一个开源项目?》
  6. 《是要精于单挑,还是要善于合作?》
  7. 《来秀一下你屎一般的代码...》
  8. 《如何区分 IT 青年的“普通/文艺/二逼”属性?》
  9. 程序员必读书籍有哪些?
  10. 你经常访问的技术社区或者技术博客(IT类)有哪些?
  11. 如何一行代码弄崩你的程序?我先来一发
  12. 编程基础指的是什么?
  13. 后端零起步:学哪一种比较好?
  14. 大家都用什么键盘写代码的?

爱因斯坦

程序猿崛起

关注 109896

喜欢的少年是你 关注了标签 · 9月25日

vue.js

Reactive Components for Modern Web Interfaces.

Vue.js 是一个用于创建 web 交互界面的。其特点是

  • 简洁 HTML 模板 + JSON 数据,再创建一个 Vue 实例,就这么简单。
  • 数据驱动 自动追踪依赖的模板表达式和计算属性。
  • 组件化 用解耦、可复用的组件来构造界面。
  • 轻量 ~24kb min+gzip,无依赖。
  • 快速 精确有效的异步批量 DOM 更新。
  • 模块友好 通过 NPM 或 Bower 安装,无缝融入你的工作流。

官网:https://vuejs.org
GitHub:https://github.com/vuejs/vue

关注 96332

喜欢的少年是你 关注了标签 · 9月25日

docker

an open source project to pack, ship and run any application as a lightweight container ! By Lock !

关注 9288

喜欢的少年是你 关注了标签 · 9月25日

springboot

Spring Boot 项目旨在简化创建产品级的 Spring 应用和服务。你可通过它来选择不同的 Spring 平台。

关注 11622

认证与成就

  • 获得 0 次点赞
  • 获得 1 枚徽章 获得 0 枚金徽章, 获得 0 枚银徽章, 获得 1 枚铜徽章

擅长技能
编辑

(゚∀゚ )
暂时没有

开源项目 & 著作
编辑

(゚∀゚ )
暂时没有

注册于 9月25日
个人主页被 102 人浏览