GithubHelp home page GithubHelp logo

parkt90 / dis-seckill Goto Github PK

View Code? Open in Web Editor NEW
203.0 3.0 44.0 23.23 MB

⭐⭐⭐⭐SpringBoot+Zookeeper+Dubbo打造分布式高并发商品秒杀系统

License: MIT License

Java 79.18% HTML 16.37% JavaScript 4.45%
java dubbo zookeeper springboot2-x rabbbitmq

dis-seckill's Introduction

分布式高并发商品秒杀系统

介绍

本项目是在dis-seckill上改进,项目名含义为分布式秒杀系统。采用微服务**,意在提高秒杀系统的整体性能。

改进点:

秒杀系统应具备要求

  1. 高性能。秒杀涉及大量的并发读和并发写,因此支持高并发访问这点非常关键。对应的方案比如动静分离方案、热点的发现和隔离、请求的削峰与分层过滤、服务端的极致优化。
  2. 一致性。秒杀中商品减库存的实现方式同样关键。有限数量的商品在同一时刻被很多倍的请求同时来减库存,减库存又分“拍下减库存"”付款减库存“以及预扣几种。系统需要在大并发更新的过程中要保证数据的准确性。
  3. 高可用。现实中难免出现一些我们考虑不到的情况,所以要保证系统的高可用性和正确性,我们还需要设计一个planB来兜底,以便应对一些意外情况。比如高并发情况下服务的熔断和降级。

快速启动

在运行秒杀系统之前,需要安装表格第一排软件,并开启相应软件。

准备:修改mysql数据库配置,连接、账户和密码。

spring.datasource.url=jdbc:mysql://localhost:3306/seckill?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=123
(根据自己数据库配置做相应修改)

第一步;执行dis-seckill-common/schema/seckill.sql文件,初始化数据库。

第二步;如果安装了git,则可以采用下面的方式快速启动;

git clone https://github.com/parkt90/dis-seckill.git
mvn clean package

启动缓存服务:

java -jar dis-seckill-cache/target/dis-seckill-cache-0.0.1-SNAPSHOT.jar

启动用户服务:

java -jar dis-seckill-user/target/dis-seckill-user-0.0.1-SNAPSHOT.jar

启动订单服务:

java -jar dis-seckill-order/target/dis-seckill-order-0.0.1-SNAPSHOT.jar

启动商品服务:

java -jar dis-seckill-goods/target/dis-seckill-goods-0.0.1-SNAPSHOT.jar

启动消息队列服务:

java -jar dis-seckill-mq/target/dis-seckill-mq-0.0.1-SNAPSHOT.jar

启动网关服务:

java -jar dis-seckill-gateway/target/dis-seckill-gateway-0.0.1-SNAPSHOT.jar

注:启动服务时最好按上面的顺序启动。

如果将项目导入IDE中进行构建,则分别按上面的顺序启动服务模块主程序即可。

第三步;访问项目入口地址

http://localhost:8082

初始用户手机号码:13111897391,密码:000000

项目架构图

项目架构图

项目入门

  • 模块介绍

    • dis-seckill-common:通用模块

    • dis-seckill-user:用户模块

    • dis-seckill-goods:商品模块

    • dis-seckill-order:订单模块

    • dis-seckill-gateway:网关模块

    • dis-seckill-cache:缓存模块

    • dis-seckill-mq:消息队列模块

      用户请求全部交由Gateway模块处理,Gateway模块使用RPC(远程过程调用)的方式调用其他模块提供的服务完成业务处理。

  • 秒杀流程图

秒杀流程图

  • 秒杀方案介绍

设计方案

  • 前端文件资源路径dis-seckill-gateway\src\main\resources\

TODO

Q&A

Q&A
前后端交互接口定义
前后端交互接口逻辑实现
Redis中存储的数据
使用分布式锁解决恶意用户重复注册问题
拦截器HandlerInterceptor的使用
Rabbitmq如何保证消息的可靠投递(推荐文章)
redismysql如何实现双删一致性(推荐文章)
限流的的原理和项目中使用(近期更新)

参考资料

dis-seckill's People

Contributors

dependabot[bot] avatar grootzz avatar parkt90 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

dis-seckill's Issues

我在windows下按序启动,前五个没问题,最后启动网关报错

请问这是啥原因呢?seckillController无法注入?
ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'seckillController' defined in file [D:\dis-seckill-master\dis-seckill-master\dis-seckill-gateway\target\classes\com\seckill\dis\gateway\seckill\SeckillController.class]: Invocation of init method failed; nested exception is org.apache.dubbo.rpc.RpcException: Failed to invoke the method listGoodsVo in the service com.seckill.dis.common.api.goods.GoodsServiceApi. Tried 3 times of the providers [180.201.4.191:12346] (1/2) from the registry 127.0.0.1:2181 on the consumer 180.201.4.191 using the dubbo version 2.7.1.

关于UserVo参数

controller中的每个函数好像都会自带UserVo参数,但是前端ajax好像并没有传递用户的信息,请问这是什么原理呢

启动报错

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'providers:dubbo:com.seckill.dis.common.api.cache.DLockApi': Instantiation of bean failed; nested exception is java.lang.ExceptionInInitializerError
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1303) ~[spring-beans-5.1.7.RELEASE.jar!/:5.1.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1197) ~[spring-beans-5.1.7.RELEASE.jar!/:5.1.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555) ~[spring-beans-5.1.7.RELEASE.jar!/:5.1.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515) ~[spring-beans-5.1.7.RELEASE.jar!/:5.1.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) ~[spring-beans-5.1.7.RELEASE.jar!/:5.1.7.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.1.7.RELEASE.jar!/:5.1.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) ~[spring-beans-5.1.7.RELEASE.jar!/:5.1.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.1.7.RELEASE.jar!/:5.1.7.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:843) ~[spring-beans-5.1.7.RELEASE.jar!/:5.1.7.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:877) ~[spring-context-5.1.7.RELEASE.jar!/:5.1.7.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549) ~[spring-context-5.1.7.RELEASE.jar!/:5.1.7.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:142) ~[spring-boot-2.1.5.RELEASE.jar!/:2.1.5.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775) ~[spring-boot-2.1.5.RELEASE.jar!/:2.1.5.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) ~[spring-boot-2.1.5.RELEASE.jar!/:2.1.5.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:316) ~[spring-boot-2.1.5.RELEASE.jar!/:2.1.5.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260) ~[spring-boot-2.1.5.RELEASE.jar!/:2.1.5.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248) ~[spring-boot-2.1.5.RELEASE.jar!/:2.1.5.RELEASE]
at com.seckill.dis.cache.CacheApplication.main(CacheApplication.java:13) ~[classes!/:0.0.1-SNAPSHOT]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48) ~[dis-seckill-cache-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
at org.springframework.boot.loader.Launcher.launch(Launcher.java:87) ~[dis-seckill-cache-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
at org.springframework.boot.loader.Launcher.launch(Launcher.java:50) ~[dis-seckill-cache-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51) ~[dis-seckill-cache-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
Caused by: java.lang.ExceptionInInitializerError: null
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:na]
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499) ~[na:na]
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480) ~[na:na]
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:172) ~[spring-beans-5.1.7.RELEASE.jar!/:5.1.7.RELEASE]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:87) ~[spring-beans-5.1.7.RELEASE.jar!/:5.1.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1295) ~[spring-beans-5.1.7.RELEASE.jar!/:5.1.7.RELEASE]
... 25 common frames omitted
Caused by: java.lang.IllegalStateException: Failed to create adaptive instance: java.lang.IllegalStateException: Can't create adaptive extension interface org.apache.dubbo.rpc.Protocol, cause: Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @28f67ac7
at org.apache.dubbo.common.extension.ExtensionLoader.getAdaptiveExtension(ExtensionLoader.java:482) ~[dubbo-2.7.1.jar!/:2.7.1]
at org.apache.dubbo.config.ServiceConfig.(ServiceConfig.java:90) ~[dubbo-2.7.1.jar!/:2.7.1]
... 33 common frames omitted
Caused by: java.lang.IllegalStateException: Can't create adaptive extension interface org.apache.dubbo.rpc.Protocol, cause: Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @28f67ac7
at org.apache.dubbo.common.extension.ExtensionLoader.createAdaptiveExtension(ExtensionLoader.java:843) ~[dubbo-2.7.1.jar!/:2.7.1]
at org.apache.dubbo.common.extension.ExtensionLoader.getAdaptiveExtension(ExtensionLoader.java:478) ~[dubbo-2.7.1.jar!/:2.7.1]
... 34 common frames omitted
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @28f67ac7
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354) ~[na:na]
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297) ~[na:na]
at java.base/java.lang.reflect.Method.checkCanSetAccessible(Method.java:199) ~[na:na]
at java.base/java.lang.reflect.Method.setAccessible(Method.java:193) ~[na:na]
at javassist.ClassPool.toClass2(ClassPool.java:1181) ~[javassist-3.20.0-GA.jar!/:na]
at javassist.ClassPool.toClass(ClassPool.java:1164) ~[javassist-3.20.0-GA.jar!/:na]
at javassist.CtClass.toClass(CtClass.java:1305) ~[javassist-3.20.0-GA.jar!/:na]
at org.apache.dubbo.common.compiler.support.JavassistCompiler.doCompile(JavassistCompiler.java:83) ~[dubbo-2.7.1.jar!/:2.7.1]
at org.apache.dubbo.common.compiler.support.AbstractCompiler.compile(AbstractCompiler.java:59) ~[dubbo-2.7.1.jar!/:2.7.1]
at org.apache.dubbo.common.compiler.support.AdaptiveCompiler.compile(AdaptiveCompiler.java:45) ~[dubbo-2.7.1.jar!/:2.7.1]
at org.apache.dubbo.common.extension.ExtensionLoader.createAdaptiveExtensionClass(ExtensionLoader.java:859) ~[dubbo-2.7.1.jar!/:2.7.1]
at org.apache.dubbo.common.extension.ExtensionLoader.getAdaptiveExtensionClass(ExtensionLoader.java:852) ~[dubbo-2.7.1.jar!/:2.7.1]
at org.apache.dubbo.common.extension.ExtensionLoader.createAdaptiveExtension(ExtensionLoader.java:841) ~[dubbo-2.7.1.jar!/:2.7.1]
... 35 common frames omitted

请问这是什么原因呢

两次md5

大佬,你说将第二次加密的密码和第一次md5的固定盐值保存在数据库中,但是代码中好像第二次使用也是固定盐值啊。是不是应该将第二次随机生成的盐值保存数据库中呢

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.