├── .gitattributes
├── .gitignore
├── .idea
├── compiler.xml
├── dataSources.local.xml
├── dataSources.xml
├── dataSources
│ └── a2fed71b-6822-4e41-a514-8ab1d04ff389.xml
├── encodings.xml
├── inspectionProfiles
│ └── Project_Default.xml
├── libraries
│ ├── Maven__ch_qos_logback_logback_classic_1_2_3.xml
│ ├── Maven__ch_qos_logback_logback_core_1_1_11.xml
│ ├── Maven__com_alibaba_druid_1_1_0.xml
│ ├── Maven__com_alibaba_druid_spring_boot_starter_1_1_0.xml
│ ├── Maven__com_alibaba_fastjson_1_2_31.xml
│ ├── Maven__com_fasterxml_classmate_1_3_4.xml
│ ├── Maven__com_fasterxml_jackson_core_jackson_annotations_2_8_0.xml
│ ├── Maven__com_fasterxml_jackson_core_jackson_core_2_8_10.xml
│ ├── Maven__com_fasterxml_jackson_core_jackson_databind_2_8_10.xml
│ ├── Maven__com_google_code_gson_gson_2_8_4.xml
│ ├── Maven__com_jayway_jsonpath_json_path_2_2_0.xml
│ ├── Maven__com_vaadin_external_google_android_json_0_0_20131108_vaadin1.xml
│ ├── Maven__javax_validation_validation_api_1_1_0_Final.xml
│ ├── Maven__junit_junit_4_12.xml
│ ├── Maven__log4j_log4j_1_2_17.xml
│ ├── Maven__mysql_mysql_connector_java_5_1_44.xml
│ ├── Maven__net_jpountz_lz4_lz4_1_3_0.xml
│ ├── Maven__net_minidev_accessors_smart_1_1.xml
│ ├── Maven__net_minidev_json_smart_2_2_1.xml
│ ├── Maven__org_apache_commons_commons_pool2_2_4_2.xml
│ ├── Maven__org_apache_kafka_kafka_clients_0_10_1_1.xml
│ ├── Maven__org_apache_tomcat_embed_tomcat_embed_core_8_5_20.xml
│ ├── Maven__org_apache_tomcat_embed_tomcat_embed_el_8_5_20.xml
│ ├── Maven__org_apache_tomcat_embed_tomcat_embed_websocket_8_5_20.xml
│ ├── Maven__org_apache_tomcat_tomcat_jdbc_8_5_20.xml
│ ├── Maven__org_apache_tomcat_tomcat_juli_8_5_20.xml
│ ├── Maven__org_assertj_assertj_core_2_6_0.xml
│ ├── Maven__org_hamcrest_hamcrest_core_1_3.xml
│ ├── Maven__org_hamcrest_hamcrest_library_1_3.xml
│ ├── Maven__org_hibernate_hibernate_validator_5_3_5_Final.xml
│ ├── Maven__org_jboss_logging_jboss_logging_3_3_1_Final.xml
│ ├── Maven__org_mockito_mockito_core_1_10_19.xml
│ ├── Maven__org_mybatis_mybatis_3_4_0.xml
│ ├── Maven__org_mybatis_mybatis_spring_1_3_0.xml
│ ├── Maven__org_mybatis_spring_boot_mybatis_spring_boot_autoconfigure_1_1_1.xml
│ ├── Maven__org_mybatis_spring_boot_mybatis_spring_boot_starter_1_1_1.xml
│ ├── Maven__org_objenesis_objenesis_2_1.xml
│ ├── Maven__org_ow2_asm_asm_5_0_3.xml
│ ├── Maven__org_projectlombok_lombok_1_16_18.xml
│ ├── Maven__org_skyscreamer_jsonassert_1_4_0.xml
│ ├── Maven__org_slf4j_jcl_over_slf4j_1_7_25.xml
│ ├── Maven__org_slf4j_jul_to_slf4j_1_7_25.xml
│ ├── Maven__org_slf4j_log4j_over_slf4j_1_7_25.xml
│ ├── Maven__org_slf4j_slf4j_api_1_7_25.xml
│ ├── Maven__org_springframework_boot_spring_boot_1_5_7_RELEASE.xml
│ ├── Maven__org_springframework_boot_spring_boot_autoconfigure_1_5_7_RELEASE.xml
│ ├── Maven__org_springframework_boot_spring_boot_starter_1_5_7_RELEASE.xml
│ ├── Maven__org_springframework_boot_spring_boot_starter_jdbc_1_5_7_RELEASE.xml
│ ├── Maven__org_springframework_boot_spring_boot_starter_logging_1_5_7_RELEASE.xml
│ ├── Maven__org_springframework_boot_spring_boot_starter_test_1_5_7_RELEASE.xml
│ ├── Maven__org_springframework_boot_spring_boot_starter_tomcat_1_5_7_RELEASE.xml
│ ├── Maven__org_springframework_boot_spring_boot_starter_web_1_5_7_RELEASE.xml
│ ├── Maven__org_springframework_boot_spring_boot_test_1_5_7_RELEASE.xml
│ ├── Maven__org_springframework_boot_spring_boot_test_autoconfigure_1_5_7_RELEASE.xml
│ ├── Maven__org_springframework_data_spring_data_commons_1_13_7_RELEASE.xml
│ ├── Maven__org_springframework_data_spring_data_keyvalue_1_2_7_RELEASE.xml
│ ├── Maven__org_springframework_data_spring_data_redis_1_8_7_RELEASE.xml
│ ├── Maven__org_springframework_kafka_spring_kafka_1_1_6_RELEASE.xml
│ ├── Maven__org_springframework_retry_spring_retry_1_2_1_RELEASE.xml
│ ├── Maven__org_springframework_spring_aop_4_3_11_RELEASE.xml
│ ├── Maven__org_springframework_spring_beans_4_3_11_RELEASE.xml
│ ├── Maven__org_springframework_spring_context_4_3_11_RELEASE.xml
│ ├── Maven__org_springframework_spring_context_support_4_3_11_RELEASE.xml
│ ├── Maven__org_springframework_spring_core_4_3_11_RELEASE.xml
│ ├── Maven__org_springframework_spring_expression_4_3_11_RELEASE.xml
│ ├── Maven__org_springframework_spring_jdbc_4_3_11_RELEASE.xml
│ ├── Maven__org_springframework_spring_messaging_4_3_11_RELEASE.xml
│ ├── Maven__org_springframework_spring_oxm_4_3_11_RELEASE.xml
│ ├── Maven__org_springframework_spring_test_4_3_11_RELEASE.xml
│ ├── Maven__org_springframework_spring_tx_4_3_11_RELEASE.xml
│ ├── Maven__org_springframework_spring_web_4_3_11_RELEASE.xml
│ ├── Maven__org_springframework_spring_webmvc_4_3_11_RELEASE.xml
│ ├── Maven__org_xerial_snappy_snappy_java_1_1_2_6.xml
│ ├── Maven__org_yaml_snakeyaml_1_17.xml
│ └── Maven__redis_clients_jedis_2_9_0.xml
├── misc.xml
├── modules.xml
├── smartfox_info.xml
├── uiDesigner.xml
├── vcs.xml
└── workspace.xml
├── .mvn
└── wrapper
│ ├── MavenWrapperDownloader.java
│ └── maven-wrapper.properties
├── LICENSE
├── README.md
├── mvnw
├── mvnw.cmd
├── pom.xml
├── secondkill.log.2019-06-10.0.gz
├── seconds-kill.iml
└── src
├── main
├── java
│ └── com
│ │ └── daydreamdev
│ │ └── secondskill
│ │ ├── Kafka
│ │ └── ConsumerListen.java
│ │ ├── SecondsKillApplication.java
│ │ ├── common
│ │ ├── Limit
│ │ │ └── RedisLimit.java
│ │ ├── RedisPreheatRunner.java
│ │ ├── StockWithRedis
│ │ │ └── StockWithRedis.java
│ │ ├── stockWithRedis
│ │ │ └── RedisKeysConstant.java
│ │ └── utils
│ │ │ ├── RedisPool.java
│ │ │ ├── RedisPoolUtil.java
│ │ │ └── ScriptUtil.java
│ │ ├── controller
│ │ └── IndexController.java
│ │ ├── dao
│ │ ├── StockMapper.java
│ │ └── StockOrderMapper.java
│ │ ├── pojo
│ │ ├── Stock.java
│ │ └── StockOrder.java
│ │ └── service
│ │ ├── api
│ │ ├── OrderService.java
│ │ └── StockService.java
│ │ └── impl
│ │ ├── OrderServiceImpl.java
│ │ └── StockServiceImpl.java
└── resources
│ ├── application.properties
│ └── limit.lua
└── test
└── java
└── com
└── daydreamdev
└── secondskill
└── SecondsKillApplicationTests.java
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Built application files and Maven
2 | target/
3 | pom.xml.tag
4 | pom.xml.releaseBackup
5 | pom.xml.versionsBackup
6 | pom.xml.next
7 | release.properties
8 | dependency-reduced-pom.xml
9 | buildNumber.properties
10 | .mvn/timing.properties
11 |
12 | # Compiled class file
13 | *.class
14 |
15 | # Log file
16 | *.log
17 |
18 | # BlueJ files
19 | *.ctxt
20 |
21 | # Mobile Tools for Java (J2ME)
22 | .mtj.tmp/
23 |
24 | # Package Files #
25 | *.jar
26 | *.war
27 | *.nar
28 | *.ear
29 | *.zip
30 | *.tar.gz
31 | *.rar
32 |
33 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
34 | hs_err_pid*
35 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/.idea/dataSources.local.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | #@
7 | `
8 |
9 |
10 | master_key
11 | root
12 | *:seconds_kill
13 |
14 |
15 |
--------------------------------------------------------------------------------
/.idea/dataSources.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | mysql
6 | true
7 | com.mysql.jdbc.Driver
8 | jdbc:mysql://119.3.214.253:3306/seconds_kill
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/.idea/dataSources/a2fed71b-6822-4e41-a514-8ab1d04ff389.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | exact
6 |
7 |
8 | utf8_bin
9 |
10 |
11 | utf8_general_ci
12 |
13 |
14 | latin1_swedish_ci
15 |
16 |
17 | utf8_general_ci
18 |
19 |
20 | 1
21 | 1
22 | utf8_general_ci
23 |
24 |
25 | utf8_general_ci
26 |
27 |
28 | armscii8
29 | 0
30 |
31 |
32 | armscii8
33 | 1
34 |
35 |
36 | ascii
37 | 0
38 |
39 |
40 | ascii
41 | 1
42 |
43 |
44 | big5
45 | 0
46 |
47 |
48 | big5
49 | 1
50 |
51 |
52 | binary
53 | 1
54 |
55 |
56 | cp1250
57 | 0
58 |
59 |
60 | cp1250
61 | 0
62 |
63 |
64 | cp1250
65 | 0
66 |
67 |
68 | cp1250
69 | 1
70 |
71 |
72 | cp1250
73 | 0
74 |
75 |
76 | cp1251
77 | 0
78 |
79 |
80 | cp1251
81 | 0
82 |
83 |
84 | cp1251
85 | 1
86 |
87 |
88 | cp1251
89 | 0
90 |
91 |
92 | cp1251
93 | 0
94 |
95 |
96 | cp1256
97 | 0
98 |
99 |
100 | cp1256
101 | 1
102 |
103 |
104 | cp1257
105 | 0
106 |
107 |
108 | cp1257
109 | 1
110 |
111 |
112 | cp1257
113 | 0
114 |
115 |
116 | cp850
117 | 0
118 |
119 |
120 | cp850
121 | 1
122 |
123 |
124 | cp852
125 | 0
126 |
127 |
128 | cp852
129 | 1
130 |
131 |
132 | cp866
133 | 0
134 |
135 |
136 | cp866
137 | 1
138 |
139 |
140 | cp932
141 | 0
142 |
143 |
144 | cp932
145 | 1
146 |
147 |
148 | dec8
149 | 0
150 |
151 |
152 | dec8
153 | 1
154 |
155 |
156 | eucjpms
157 | 0
158 |
159 |
160 | eucjpms
161 | 1
162 |
163 |
164 | euckr
165 | 0
166 |
167 |
168 | euckr
169 | 1
170 |
171 |
172 | gb18030
173 | 0
174 |
175 |
176 | gb18030
177 | 1
178 |
179 |
180 | gb18030
181 | 0
182 |
183 |
184 | gb2312
185 | 0
186 |
187 |
188 | gb2312
189 | 1
190 |
191 |
192 | gbk
193 | 0
194 |
195 |
196 | gbk
197 | 1
198 |
199 |
200 | geostd8
201 | 0
202 |
203 |
204 | geostd8
205 | 1
206 |
207 |
208 | greek
209 | 0
210 |
211 |
212 | greek
213 | 1
214 |
215 |
216 | hebrew
217 | 0
218 |
219 |
220 | hebrew
221 | 1
222 |
223 |
224 | hp8
225 | 0
226 |
227 |
228 | hp8
229 | 1
230 |
231 |
232 | keybcs2
233 | 0
234 |
235 |
236 | keybcs2
237 | 1
238 |
239 |
240 | koi8r
241 | 0
242 |
243 |
244 | koi8r
245 | 1
246 |
247 |
248 | koi8u
249 | 0
250 |
251 |
252 | koi8u
253 | 1
254 |
255 |
256 | latin1
257 | 0
258 |
259 |
260 | latin1
261 | 0
262 |
263 |
264 | latin1
265 | 0
266 |
267 |
268 | latin1
269 | 0
270 |
271 |
272 | latin1
273 | 0
274 |
275 |
276 | latin1
277 | 0
278 |
279 |
280 | latin1
281 | 0
282 |
283 |
284 | latin1
285 | 1
286 |
287 |
288 | latin2
289 | 0
290 |
291 |
292 | latin2
293 | 0
294 |
295 |
296 | latin2
297 | 0
298 |
299 |
300 | latin2
301 | 1
302 |
303 |
304 | latin2
305 | 0
306 |
307 |
308 | latin5
309 | 0
310 |
311 |
312 | latin5
313 | 1
314 |
315 |
316 | latin7
317 | 0
318 |
319 |
320 | latin7
321 | 0
322 |
323 |
324 | latin7
325 | 1
326 |
327 |
328 | latin7
329 | 0
330 |
331 |
332 | macce
333 | 0
334 |
335 |
336 | macce
337 | 1
338 |
339 |
340 | macroman
341 | 0
342 |
343 |
344 | macroman
345 | 1
346 |
347 |
348 | sjis
349 | 0
350 |
351 |
352 | sjis
353 | 1
354 |
355 |
356 | swe7
357 | 0
358 |
359 |
360 | swe7
361 | 1
362 |
363 |
364 | tis620
365 | 0
366 |
367 |
368 | tis620
369 | 1
370 |
371 |
372 | ucs2
373 | 0
374 |
375 |
376 | ucs2
377 | 0
378 |
379 |
380 | ucs2
381 | 0
382 |
383 |
384 | ucs2
385 | 0
386 |
387 |
388 | ucs2
389 | 0
390 |
391 |
392 | ucs2
393 | 0
394 |
395 |
396 | ucs2
397 | 1
398 |
399 |
400 | ucs2
401 | 0
402 |
403 |
404 | ucs2
405 | 0
406 |
407 |
408 | ucs2
409 | 0
410 |
411 |
412 | ucs2
413 | 0
414 |
415 |
416 | ucs2
417 | 0
418 |
419 |
420 | ucs2
421 | 0
422 |
423 |
424 | ucs2
425 | 0
426 |
427 |
428 | ucs2
429 | 0
430 |
431 |
432 | ucs2
433 | 0
434 |
435 |
436 | ucs2
437 | 0
438 |
439 |
440 | ucs2
441 | 0
442 |
443 |
444 | ucs2
445 | 0
446 |
447 |
448 | ucs2
449 | 0
450 |
451 |
452 | ucs2
453 | 0
454 |
455 |
456 | ucs2
457 | 0
458 |
459 |
460 | ucs2
461 | 0
462 |
463 |
464 | ucs2
465 | 0
466 |
467 |
468 | ucs2
469 | 0
470 |
471 |
472 | ucs2
473 | 0
474 |
475 |
476 | ucs2
477 | 0
478 |
479 |
480 | ujis
481 | 0
482 |
483 |
484 | ujis
485 | 1
486 |
487 |
488 | utf16
489 | 0
490 |
491 |
492 | utf16
493 | 0
494 |
495 |
496 | utf16
497 | 0
498 |
499 |
500 | utf16
501 | 0
502 |
503 |
504 | utf16
505 | 0
506 |
507 |
508 | utf16
509 | 0
510 |
511 |
512 | utf16
513 | 1
514 |
515 |
516 | utf16
517 | 0
518 |
519 |
520 | utf16
521 | 0
522 |
523 |
524 | utf16
525 | 0
526 |
527 |
528 | utf16
529 | 0
530 |
531 |
532 | utf16
533 | 0
534 |
535 |
536 | utf16
537 | 0
538 |
539 |
540 | utf16
541 | 0
542 |
543 |
544 | utf16
545 | 0
546 |
547 |
548 | utf16
549 | 0
550 |
551 |
552 | utf16
553 | 0
554 |
555 |
556 | utf16
557 | 0
558 |
559 |
560 | utf16
561 | 0
562 |
563 |
564 | utf16
565 | 0
566 |
567 |
568 | utf16
569 | 0
570 |
571 |
572 | utf16
573 | 0
574 |
575 |
576 | utf16
577 | 0
578 |
579 |
580 | utf16
581 | 0
582 |
583 |
584 | utf16
585 | 0
586 |
587 |
588 | utf16
589 | 0
590 |
591 |
592 | utf16le
593 | 0
594 |
595 |
596 | utf16le
597 | 1
598 |
599 |
600 | utf32
601 | 0
602 |
603 |
604 | utf32
605 | 0
606 |
607 |
608 | utf32
609 | 0
610 |
611 |
612 | utf32
613 | 0
614 |
615 |
616 | utf32
617 | 0
618 |
619 |
620 | utf32
621 | 0
622 |
623 |
624 | utf32
625 | 1
626 |
627 |
628 | utf32
629 | 0
630 |
631 |
632 | utf32
633 | 0
634 |
635 |
636 | utf32
637 | 0
638 |
639 |
640 | utf32
641 | 0
642 |
643 |
644 | utf32
645 | 0
646 |
647 |
648 | utf32
649 | 0
650 |
651 |
652 | utf32
653 | 0
654 |
655 |
656 | utf32
657 | 0
658 |
659 |
660 | utf32
661 | 0
662 |
663 |
664 | utf32
665 | 0
666 |
667 |
668 | utf32
669 | 0
670 |
671 |
672 | utf32
673 | 0
674 |
675 |
676 | utf32
677 | 0
678 |
679 |
680 | utf32
681 | 0
682 |
683 |
684 | utf32
685 | 0
686 |
687 |
688 | utf32
689 | 0
690 |
691 |
692 | utf32
693 | 0
694 |
695 |
696 | utf32
697 | 0
698 |
699 |
700 | utf32
701 | 0
702 |
703 |
704 | utf8
705 | 0
706 |
707 |
708 | utf8
709 | 0
710 |
711 |
712 | utf8
713 | 0
714 |
715 |
716 | utf8
717 | 0
718 |
719 |
720 | utf8
721 | 0
722 |
723 |
724 | utf8
725 | 0
726 |
727 |
728 | utf8
729 | 1
730 |
731 |
732 | utf8
733 | 0
734 |
735 |
736 | utf8
737 | 0
738 |
739 |
740 | utf8
741 | 0
742 |
743 |
744 | utf8
745 | 0
746 |
747 |
748 | utf8
749 | 0
750 |
751 |
752 | utf8
753 | 0
754 |
755 |
756 | utf8
757 | 0
758 |
759 |
760 | utf8
761 | 0
762 |
763 |
764 | utf8
765 | 0
766 |
767 |
768 | utf8
769 | 0
770 |
771 |
772 | utf8
773 | 0
774 |
775 |
776 | utf8
777 | 0
778 |
779 |
780 | utf8
781 | 0
782 |
783 |
784 | utf8
785 | 0
786 |
787 |
788 | utf8
789 | 0
790 |
791 |
792 | utf8
793 | 0
794 |
795 |
796 | utf8
797 | 0
798 |
799 |
800 | utf8
801 | 0
802 |
803 |
804 | utf8
805 | 0
806 |
807 |
808 | utf8
809 | 0
810 |
811 |
812 | utf8mb4
813 | 0
814 |
815 |
816 | utf8mb4
817 | 0
818 |
819 |
820 | utf8mb4
821 | 0
822 |
823 |
824 | utf8mb4
825 | 0
826 |
827 |
828 | utf8mb4
829 | 0
830 |
831 |
832 | utf8mb4
833 | 0
834 |
835 |
836 | utf8mb4
837 | 1
838 |
839 |
840 | utf8mb4
841 | 0
842 |
843 |
844 | utf8mb4
845 | 0
846 |
847 |
848 | utf8mb4
849 | 0
850 |
851 |
852 | utf8mb4
853 | 0
854 |
855 |
856 | utf8mb4
857 | 0
858 |
859 |
860 | utf8mb4
861 | 0
862 |
863 |
864 | utf8mb4
865 | 0
866 |
867 |
868 | utf8mb4
869 | 0
870 |
871 |
872 | utf8mb4
873 | 0
874 |
875 |
876 | utf8mb4
877 | 0
878 |
879 |
880 | utf8mb4
881 | 0
882 |
883 |
884 | utf8mb4
885 | 0
886 |
887 |
888 | utf8mb4
889 | 0
890 |
891 |
892 | utf8mb4
893 | 0
894 |
895 |
896 | utf8mb4
897 | 0
898 |
899 |
900 | utf8mb4
901 | 0
902 |
903 |
904 | utf8mb4
905 | 0
906 |
907 |
908 | utf8mb4
909 | 0
910 |
911 |
912 | utf8mb4
913 | 0
914 |
915 |
918 |
921 |
922 | 1
923 | int(11) unsigned|0
924 | 1
925 | 1
926 | normal
927 |
928 |
929 | 2
930 | 名称
931 | varchar(50)|0
932 | 1
933 | ''
934 | normal
935 |
936 |
937 | 3
938 | 库存
939 | int(11)|0
940 | 1
941 | normal
942 |
943 |
944 | 4
945 | 已售
946 | int(11)|0
947 | 1
948 | normal
949 |
950 |
951 | 5
952 | 乐观锁,版本号
953 | int(11)|0
954 | 1
955 | normal
956 |
957 |
958 | 1
959 | id
960 | 1
961 |
962 |
963 | 1
964 | int(11) unsigned|0
965 | 1
966 | 1
967 | normal
968 |
969 |
970 | 2
971 | 库存ID
972 | int(11)|0
973 | 1
974 | normal
975 |
976 |
977 | 3
978 | 商品名称
979 | varchar(30)|0
980 | 1
981 | ''
982 | normal
983 |
984 |
985 | 4
986 | 创建时间
987 | timestamp|0
988 | 1
989 | CURRENT_TIMESTAMP
990 | normal
991 | CURRENT_TIMESTAMP
992 |
993 |
994 | 1
995 | id
996 | 1
997 |
998 |
999 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/Project_Default.xml:
--------------------------------------------------------------------------------
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 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__ch_qos_logback_logback_classic_1_2_3.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__ch_qos_logback_logback_core_1_1_11.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__com_alibaba_druid_1_1_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__com_alibaba_druid_spring_boot_starter_1_1_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__com_alibaba_fastjson_1_2_31.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__com_fasterxml_classmate_1_3_4.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_annotations_2_8_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_core_2_8_10.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_databind_2_8_10.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__com_google_code_gson_gson_2_8_4.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__com_jayway_jsonpath_json_path_2_2_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__com_vaadin_external_google_android_json_0_0_20131108_vaadin1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__javax_validation_validation_api_1_1_0_Final.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__junit_junit_4_12.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__log4j_log4j_1_2_17.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__mysql_mysql_connector_java_5_1_44.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__net_jpountz_lz4_lz4_1_3_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__net_minidev_accessors_smart_1_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__net_minidev_json_smart_2_2_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_apache_commons_commons_pool2_2_4_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_apache_kafka_kafka_clients_0_10_1_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_core_8_5_20.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_el_8_5_20.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_websocket_8_5_20.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_apache_tomcat_tomcat_jdbc_8_5_20.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_apache_tomcat_tomcat_juli_8_5_20.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_assertj_assertj_core_2_6_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_3.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_hamcrest_hamcrest_library_1_3.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_hibernate_hibernate_validator_5_3_5_Final.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_jboss_logging_jboss_logging_3_3_1_Final.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_mockito_mockito_core_1_10_19.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_mybatis_mybatis_3_4_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_mybatis_mybatis_spring_1_3_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_mybatis_spring_boot_mybatis_spring_boot_autoconfigure_1_1_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_mybatis_spring_boot_mybatis_spring_boot_starter_1_1_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_objenesis_objenesis_2_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_ow2_asm_asm_5_0_3.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_projectlombok_lombok_1_16_18.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_skyscreamer_jsonassert_1_4_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_slf4j_jcl_over_slf4j_1_7_25.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_slf4j_jul_to_slf4j_1_7_25.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_slf4j_log4j_over_slf4j_1_7_25.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_slf4j_slf4j_api_1_7_25.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_boot_spring_boot_1_5_7_RELEASE.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_boot_spring_boot_autoconfigure_1_5_7_RELEASE.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_1_5_7_RELEASE.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_jdbc_1_5_7_RELEASE.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_logging_1_5_7_RELEASE.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_test_1_5_7_RELEASE.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_tomcat_1_5_7_RELEASE.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_web_1_5_7_RELEASE.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_boot_spring_boot_test_1_5_7_RELEASE.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_boot_spring_boot_test_autoconfigure_1_5_7_RELEASE.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_data_spring_data_commons_1_13_7_RELEASE.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_data_spring_data_keyvalue_1_2_7_RELEASE.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_data_spring_data_redis_1_8_7_RELEASE.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_kafka_spring_kafka_1_1_6_RELEASE.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_retry_spring_retry_1_2_1_RELEASE.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_spring_aop_4_3_11_RELEASE.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_spring_beans_4_3_11_RELEASE.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_spring_context_4_3_11_RELEASE.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_spring_context_support_4_3_11_RELEASE.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_spring_core_4_3_11_RELEASE.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_spring_expression_4_3_11_RELEASE.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_spring_jdbc_4_3_11_RELEASE.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_spring_messaging_4_3_11_RELEASE.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_spring_oxm_4_3_11_RELEASE.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_spring_test_4_3_11_RELEASE.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_spring_tx_4_3_11_RELEASE.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_spring_web_4_3_11_RELEASE.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_spring_webmvc_4_3_11_RELEASE.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_xerial_snappy_snappy_java_1_1_2_6.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_yaml_snakeyaml_1_17.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__redis_clients_jedis_2_9_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/smartfox_info.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/uiDesigner.xml:
--------------------------------------------------------------------------------
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 |
91 |
92 |
93 |
94 | -
95 |
96 |
97 |
98 |
99 | -
100 |
101 |
102 | -
103 |
104 |
105 | -
106 |
107 |
108 | -
109 |
110 |
111 | -
112 |
113 |
114 |
115 |
116 | -
117 |
118 |
119 | -
120 |
121 |
122 |
123 |
124 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.mvn/wrapper/MavenWrapperDownloader.java:
--------------------------------------------------------------------------------
1 | /*
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. See the NOTICE file
4 | distributed with this work for additional information
5 | regarding copyright ownership. The ASF licenses this file
6 | to you under the Apache License, Version 2.0 (the
7 | "License"); you may not use this file except in compliance
8 | with the License. You may obtain a copy of the License at
9 |
10 | https://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an
14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | KIND, either express or implied. See the License for the
16 | specific language governing permissions and limitations
17 | under the License.
18 | */
19 |
20 | import java.io.File;
21 | import java.io.FileInputStream;
22 | import java.io.FileOutputStream;
23 | import java.io.IOException;
24 | import java.net.URL;
25 | import java.nio.channels.Channels;
26 | import java.nio.channels.ReadableByteChannel;
27 | import java.util.Properties;
28 |
29 | public class MavenWrapperDownloader {
30 |
31 | /**
32 | * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
33 | */
34 | private static final String DEFAULT_DOWNLOAD_URL =
35 | "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar";
36 |
37 | /**
38 | * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
39 | * use instead of the default one.
40 | */
41 | private static final String MAVEN_WRAPPER_PROPERTIES_PATH =
42 | ".mvn/wrapper/maven-wrapper.properties";
43 |
44 | /**
45 | * Path where the maven-wrapper.jar will be saved to.
46 | */
47 | private static final String MAVEN_WRAPPER_JAR_PATH =
48 | ".mvn/wrapper/maven-wrapper.jar";
49 |
50 | /**
51 | * Name of the property which should be used to override the default download url for the wrapper.
52 | */
53 | private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl";
54 |
55 | public static void main(String args[]) {
56 | System.out.println("- Downloader started");
57 | File baseDirectory = new File(args[0]);
58 | System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath());
59 |
60 | // If the maven-wrapper.properties exists, read it and check if it contains a custom
61 | // wrapperUrl parameter.
62 | File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH);
63 | String url = DEFAULT_DOWNLOAD_URL;
64 | if(mavenWrapperPropertyFile.exists()) {
65 | FileInputStream mavenWrapperPropertyFileInputStream = null;
66 | try {
67 | mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile);
68 | Properties mavenWrapperProperties = new Properties();
69 | mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream);
70 | url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url);
71 | } catch (IOException e) {
72 | System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'");
73 | } finally {
74 | try {
75 | if(mavenWrapperPropertyFileInputStream != null) {
76 | mavenWrapperPropertyFileInputStream.close();
77 | }
78 | } catch (IOException e) {
79 | // Ignore ...
80 | }
81 | }
82 | }
83 | System.out.println("- Downloading from: : " + url);
84 |
85 | File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
86 | if(!outputFile.getParentFile().exists()) {
87 | if(!outputFile.getParentFile().mkdirs()) {
88 | System.out.println(
89 | "- ERROR creating output direcrory '" + outputFile.getParentFile().getAbsolutePath() + "'");
90 | }
91 | }
92 | System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
93 | try {
94 | downloadFileFromURL(url, outputFile);
95 | System.out.println("Done");
96 | System.exit(0);
97 | } catch (Throwable e) {
98 | System.out.println("- Error downloading");
99 | e.printStackTrace();
100 | System.exit(1);
101 | }
102 | }
103 |
104 | private static void downloadFileFromURL(String urlString, File destination) throws Exception {
105 | URL website = new URL(urlString);
106 | ReadableByteChannel rbc;
107 | rbc = Channels.newChannel(website.openStream());
108 | FileOutputStream fos = new FileOutputStream(destination);
109 | fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
110 | fos.close();
111 | rbc.close();
112 | }
113 |
114 | }
115 |
--------------------------------------------------------------------------------
/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip
2 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 gongfukangEE
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 如何设计一个秒杀系统
2 |
3 | ## 系统的特点
4 |
5 | - 高性能:秒杀涉及大量的并发读和并发写,因此支持高并发访问这点非常关键
6 | - 一致性:秒杀商品减库存的实现方式同样关键,有限数量的商品在同一时刻被很多倍的请求同时来减库存,在大并发更新的过程中都要保证数据的准确性。
7 | - 高可用:秒杀时会在一瞬间涌入大量的流量,为了避免系统宕机,保证高可用,需要做好流量限制
8 |
9 | ## 优化思路
10 |
11 | - 后端优化:将请求尽量拦截在系统上游
12 | - 限流:屏蔽掉无用的流量,允许少部分流量走后端。假设现在库存为 10,有 1000 个购买请求,最终只有 10 个可以成功,99% 的请求都是无效请求
13 | - 削峰:秒杀请求在时间上高度集中于某一个时间点,瞬时流量容易压垮系统,因此需要对流量进行削峰处理,缓冲瞬时流量,尽量让服务器对资源进行平缓处理
14 | - 异步:将同步请求转换为异步请求,来提高并发量,本质也是削峰处理
15 | - 利用缓存:创建订单时,每次都需要先查询判断库存,只有少部分成功的请求才会创建订单,因此可以将商品信息放在缓存中,减少数据库查询
16 | - 负载均衡:利用 Nginx 等使用多个服务器并发处理请求,减少单个服务器压力
17 | - 前端优化:
18 | - 限流:前端答题或验证码,来分散用户的请求
19 | - 禁止重复提交:限定每个用户发起一次秒杀后,需等待才可以发起另一次请求,从而减少用户的重复请求
20 | - 本地标记:用户成功秒杀到商品后,将提交按钮置灰,禁止用户再次提交请求
21 | - 动静分离:将前端静态数据直接缓存到离用户最近的地方,比如用户浏览器、CDN 或者服务端的缓存中
22 | - 防作弊优化:
23 | - 隐藏秒杀接口:如果秒杀地址直接暴露,在秒杀开始前可能会被恶意用户来刷接口,因此需要在没到秒杀开始时间不能获取秒杀接口,只有秒杀开始了,才返回秒杀地址 url 和验证 MD5,用户拿到这两个数据才可以进行秒杀
24 | - 同一个账号多次发出请求:在前端优化的禁止重复提交可以进行优化;也可以使用 Redis 标志位,每个用户的所有请求都尝试在 Redis 中插入一个 `userId_secondsKill` 标志位,成功插入的才可以执行后续的秒杀逻辑,其他被过滤掉,执行完秒杀逻辑后,删除标志位
25 | - 多个账号一次性发出多个请求:一般这种请求都来自同一个 IP 地址,可以检测 IP 的请求频率,如果过于频繁则弹出一个验证码
26 | - 多个账号不同 IP 发起不同请求:这种一般都是僵尸账号,检测账号的活跃度或者等级等信息,来进行限制。比如微博抽奖,用 iphone 的年轻女性用户中奖几率更大。通过用户画像限制僵尸号无法参与秒杀或秒杀不能成功
27 |
28 | ## 代码优化
29 |
30 | 代码整体思路参考的 [@crossoverJie](),做了以下几点变动
31 |
32 | 1. 将 SSM 换成 SpringBoot,开箱即用,替换 Mapper XML 为注解,去掉 Dubbo 和 Zookeeper
33 | 2. 原项目中依赖了开发者自己的开源包 [distributed-redis-tool](),本项目将用到的限流部分直接集成到代码中
34 | 3. 加入缓存预热,在秒杀开始前,将库存信息读到缓存中,并暴露数据库和缓存重置方法便于服务器部署压测
35 | 4. 缓存更新逻辑中加入 Redis 事务,避免脏数据
36 | 5. 将 Kafka-client 替换为 spring-kafka,自动配置,通过 KafkaTemplate 和 Listen 进行消息的生产和消费,采用 Gson 进行 Kafka 消息序列化和反序列化,精简大量代码
37 |
38 | ### Jmeter 压测
39 |
40 | ![]()
41 |
42 | **测试流程如下:**
43 |
44 | 首先下载 JMeter 安装包 可以去官网下载:http://jmeter.apache.org
45 |
46 | windows 环境下载 zip 安装包,然后将下载的文件进行解压,进入 bin 目录运行 jmeter.bat 即可。
47 |
48 | 接下来是 Jmeter 测试计划设置:
49 |
50 | (1)在测试计划上右键新建一个线程组
51 |
52 | ![]()
53 |
54 | 线程组属性内可以修改线程数、Ramp-Up 时间和循环次数。
55 |
56 | ![]()
57 |
58 | (2)在线程组上右键添加 HTTP 请求
59 |
60 | ![]()
61 |
62 | 其属性包括 WEB 服务器的协议、服务器名称或 IP 和端口号,HTTP 请求的方法和路径。
63 |
64 | ![]()
65 |
66 | (3)在HTTP请求上右键添加一个监听器,可以根据自己的需求添加汇总报告、查看结果树等等。
67 |
68 | ![]()
69 |
70 | 如下图所示为汇总报告,可以查看异常比例和吞吐量,方便调优。
71 |
72 | ![]()
73 |
74 | 这样一个简单的 Jmeter 测试计划就算添加完了。一个 HTTP 请求对应一个接口,可以添加多个 HTTP 请求 以达到多个接口同时检测的需求。
75 |
76 | ### 0. 基本秒杀逻辑
77 |
78 | ```java
79 | @Override
80 | public int createWrongOrder(int sid) throws Exception {
81 | // 数据库校验库存
82 | Stock stock = checkStock(sid);
83 | // 扣库存(无锁)
84 | saleStock(stock);
85 | // 生成订单
86 | int res = createOrder(stock);
87 | return res;
88 | }
89 | private Stock checkStock(int sid) throws Exception {
90 | Stock stock = stockService.getStockById(sid);
91 | if (stock.getCount() < 1) {
92 | throw new RuntimeException("库存不足");
93 | }
94 | return stock;
95 | }
96 | private int saleStock(Stock stock) {
97 | stock.setSale(stock.getSale() + 1);
98 | stock.setCount(stock.getCount() - 1);
99 | return stockService.updateStockById(stock);
100 | }
101 | private int createOrder(Stock stock) throws Exception {
102 | StockOrder order = new StockOrder();
103 | order.setSid(stock.getId());
104 | order.setName(stock.getName());
105 | order.setCreateTime(new Date());
106 | int res = orderMapper.insertSelective(order);
107 | if (res == 0) {
108 | throw new RuntimeException("创建订单失败");
109 | }
110 | return res;
111 | }
112 | // 扣库存 Mapper 文件
113 | @Update("UPDATE stock SET count = #{count, jdbcType = INTEGER}, name = #{name, jdbcType = VARCHAR}, " + "sale = #{sale,jdbcType = INTEGER},version = #{version,jdbcType = INTEGER} " + "WHERE id = #{id, jdbcType = INTEGER}")
114 | ```
115 |
116 | ### 1. 乐观锁更新库存,解决超卖问题
117 |
118 | 超卖问题出现的场景
119 |
120 | 
121 |
122 | 悲观锁虽然可以解决超卖问题,但是加锁的时间可能会很长,会长时间的限制其他用户的访问,导致很多请求等待锁,卡死在这里,如果这种请求很多就会耗尽连接,系统出现异常。乐观锁默认不加锁,更失败就直接返回抢购失败,可以承受较高并发
123 |
124 | 
125 |
126 | ```java
127 | @Override
128 | public int createOptimisticOrder(int sid) throws Exception {
129 | // 校验库存
130 | Stock stock = checkStock(sid);
131 | // 乐观锁更新
132 | saleStockOptimstic(stock);
133 | // 创建订单
134 | int id = createOrder(stock);
135 | return id;
136 | }
137 | // 乐观锁 Mapper 文件
138 | @Update("UPDATE stock SET count = count - 1, sale = sale + 1, version = version + 1 WHERE " +
139 | "id = #{id, jdbcType = INTEGER} AND version = #{version, jdbcType = INTEGER}")
140 | ```
141 |
142 | ### 2. Redis 计数限流
143 |
144 | 根据前面的优化分析,假设现在有 10 个商品,有 1000 个并发秒杀请求,最终只有 10 个订单会成功创建,也就是说有 990 的请求是无效的,这些无效的请求也会给数据库带来压力,因此可以在在请求落到数据库之前就将无效的请求过滤掉,将并发控制在一个可控的范围,这样落到数据库的压力就小很多
145 |
146 | 关于限流的方法,可以看这篇博客[浅析限流算法](),由于计数限流实现起来比较简单,因此采用计数限流,限流的实现可以直接使用 Guava 的 RateLimit 方法,但是由于后续需要将实例通过 Nginx 实现负载均衡,这里选用 Redis 实现分布式限流
147 |
148 | 在 `RedisPool` 中对 `Jedis` 线程池进行了简单的封装,封装了初始化和关闭方法,同时在 `RedisPoolUtil` 中对 Jedis 常用 API 进行简单封装,每个方法调用完毕则关闭 Jedis 连接。
149 |
150 | 限流要保证写入 Redis 操作的原子性,因此利用 Redis 的单线程机制,通过 LUA 脚本来完成。
151 |
152 | 
153 |
154 | ```java
155 | @Slf4j
156 | public class RedisLimit {
157 |
158 | private static final int FAIL_CODE = 0;
159 |
160 | private static Integer limit = 5;
161 |
162 | /**
163 | * Redis 限流
164 | */
165 | public static Boolean limit() {
166 | Jedis jedis = null;
167 | Object result = null;
168 | try {
169 | // 获取 jedis 实例
170 | jedis = RedisPool.getJedis();
171 | // 解析 Lua 文件
172 | String script = ScriptUtil.getScript("limit.lua");
173 | // 请求限流
174 | String key = String.valueOf(System.currentTimeMillis() / 1000);
175 | // 计数限流
176 | result = jedis.eval(script, Collections.singletonList(key), Collections.singletonList(String.valueOf(limit)));
177 | if (FAIL_CODE != (Long) result) {
178 | log.info("成功获取令牌");
179 | return true;
180 | }
181 | } catch (Exception e) {
182 | log.error(limit, e);
183 | } finally {
184 | RedisPool.jedisPoolClose(jedis);
185 | }
186 | return false;
187 | }
188 | }
189 | // 在 Controller 中,每个请求到来先取令牌,获取到令牌再执行后续操作,获取不到直接返回 ERROR
190 | public String createOptimisticLimitOrder(HttpServletRequest request, int sid) {
191 | int res = 0;
192 | try {
193 | if (RedisLimit.limit()) {
194 | res = orderService.createOptimisticOrder(sid);
195 | }
196 | } catch (Exception e) {
197 | log.error("Exception: " + e);
198 | }
199 | return res == 1 ? success : error;
200 | }
201 | ```
202 |
203 | ### 3. Redis 缓存商品库存信息
204 |
205 | 虽然限流能够过滤掉一些无效的请求,但是还是会有很多请求落在数据库上,通过 `Druid` 监控可以看出,实时查询库存的语句被大量调用,对于每个没有被过滤掉的请求,都会去数据库查询库存来判断库存是否充足,对于这个查询可以放在缓存 Redis 中,Redis 的数据是存放在内存中的,速度快很多。
206 |
207 | ![]()
208 |
209 | #### 缓存预热
210 |
211 | 在秒杀开始前,需要将秒杀商品信息提前缓存到 Redis 中,这么秒杀开始时则直接从 Redis 中读取,也就是缓存预热,Springboot 中开发者通过 `implement ApplicationRunner` 来设定 SpringBoot 启动后立即执行的方法
212 |
213 | ```java
214 | @Component
215 | public class RedisPreheatRunner implements ApplicationRunner {
216 |
217 | @Autowired
218 | private StockService stockService;
219 |
220 | @Override
221 | public void run(ApplicationArguments args) throws Exception {
222 | // 从数据库中查询热卖商品,商品 id 为 1
223 | Stock stock = stockService.getStockById(1);
224 | // 删除旧缓存
225 | RedisPoolUtil.del(RedisKeysConstant.STOCK_COUNT + stock.getCount());
226 | RedisPoolUtil.del(RedisKeysConstant.STOCK_SALE + stock.getSale());
227 | RedisPoolUtil.del(RedisKeysConstant.STOCK_VERSION + stock.getVersion());
228 | //缓存预热
229 | int sid = stock.getId();
230 | RedisPoolUtil.set(RedisKeysConstant.STOCK_COUNT + sid, String.valueOf(stock.getCount()));
231 | RedisPoolUtil.set(RedisKeysConstant.STOCK_SALE + sid, String.valueOf(stock.getSale()));
232 | RedisPoolUtil.set(RedisKeysConstant.STOCK_VERSION + sid, String.valueOf(stock.getVersion()));
233 | }
234 | }
235 | ```
236 |
237 | #### 缓存和数据一致性
238 |
239 | 缓存和 DB 的一致性是一个讨论很多的问题,推荐看参考中的 [使用缓存的正确姿势](),首先看下先更新数据库,再更新缓存策略,假设 A、B 两个线程,A 成功更新数据,在要更新缓存时,A 的时间片用完了,B 更新了数据库接着更新了缓存,这是 CPU 再分配给 A,则 A 又更新了缓存,这种情况下缓存中就是脏数据,具体逻辑如下图所示:
240 |
241 | ![]()
242 |
243 | 那么,如果避免这个问题呢?就是缓存不做更新,仅做删除,先更新数据库再删除缓存。对于上面的问题,A 更新了数据库,还没来得及删除缓存,B 又更新了数据库,接着删除了缓存,然后 A 删除了缓存,这样只有下次缓存未命中时,才会从数据库中重建缓存,避免了脏数据。但是,也会有极端情况出现脏数据,A 做查询操作,没有命中缓存,从数据库中查询,但是还没来得及更新缓存,B 就更新了数据库,接着删除了缓存,然后 A 又重建了缓存,这时 A 中的就是脏数据,如下图所示。但是这种极端情况需要数据库的写操作前进入数据库,又晚于写操作删除缓存来更新缓存,发生的概率极其小,不过为了避免这种情况,可以为缓存设置过期时间。
244 |
245 | ![]()
246 |
247 | 安装先更新数据库再删除缓存的策略来执行,代码如下所示:
248 |
249 | ```java
250 | @Override
251 | public int createOrderWithLimitAndRedis(int sid) throws Exception {
252 | // 校验库存,从 Redis 中获取
253 | Stock stock = checkStockWithRedis(sid);
254 | // 乐观锁更新库存和Redis
255 | saleStockOptimsticWithRedis(stock);
256 | // 创建订单
257 | int res = createOrder(stock);
258 | return res;
259 | }
260 | // Redis 校验库存
261 | private Stock checkStockWithRedisWithDel(int sid) throws Exception {
262 | Integer count = null;
263 | Integer sale = null;
264 | Integer version = null;
265 | List data = RedisPoolUtil.listGet(RedisKeysConstant.STOCK + sid);
266 | if (data.size() == 0) {
267 | // Redis 不存在,先从数据库中获取,再放到 Redis 中
268 | Stock newStock = stockService.getStockById(sid);
269 | RedisPoolUtil.listPut(RedisKeysConstant.STOCK + newStock.getId(), String.valueOf(newStock.getCount()),
270 | String.valueOf(newStock.getSale()), String.valueOf(newStock.getVersion()));
271 | count = newStock.getCount();
272 | sale = newStock.getSale();
273 | version = newStock.getVersion();
274 | } else {
275 | count = Integer.parseInt(data.get(0));
276 | sale = Integer.parseInt(data.get(1));
277 | version = Integer.parseInt(data.get(2));
278 | }
279 | if (count < 1) {
280 | log.info("库存不足");
281 | throw new RuntimeException("库存不足 Redis currentCount: " + sale);
282 | }
283 | Stock stock = new Stock();
284 | stock.setId(sid);
285 | stock.setCount(count);
286 | stock.setSale(sale);
287 | stock.setVersion(version);
288 | // 此处应该是热更新,但是在数据库中只有一个商品,所以直接赋值
289 | stock.setName("手机");
290 | return stock;
291 | }
292 | private void saleStockOptimsticWithRedisWithDel(Stock stock) throws Exception {
293 | // 乐观锁更新数据库
294 | int res = stockService.updateStockByOptimistic(stock);
295 | // 删除缓存,应该使用 Redis 事务
296 | RedisPoolUtil.del(RedisKeysConstant.STOCK + stock.getId());
297 | log.info("删除缓存成功");
298 | if (res == 0) {
299 | throw new RuntimeException("并发更新库存失败");
300 | }
301 | }
302 | ```
303 |
304 | 在 Jmeter 压力测试中,并发效果并不好,跟前面的限流并发差不多,观察 Redis 中的数据看出,由于每次都删除缓存,因此导致多次缓存都不能命中,能命中缓存的次数很少,因此这种方案并不可取。
305 |
306 | 考虑到使用乐观锁更新数据库,因此在使用先更新数据库再更新缓存的策略中,实际情况如下所示
307 |
308 | ![]()
309 |
310 | 在 A 未更新缓存阶段,虽然 B 从缓存中获取到的库存信息脏数据,但是,乐观锁使得 B 在更新数据库时失败,这时 A 又更新了缓存,则保证了数据的最终一致性,并且由于缓存一直都可以命中,对并发量的提升也是很显著的。
311 |
312 | ```java
313 | @Override
314 | public int createOrderWithLimitAndRedis(int sid) throws Exception {
315 | // 校验库存,从 Redis 中获取
316 | Stock stock = checkStockWithRedis(sid);
317 | // 乐观锁更新库存和Redis
318 | saleStockOptimsticWithRedis(stock);
319 | // 创建订单
320 | int res = createOrder(stock);
321 | return res;
322 | }
323 | // Redis 中校验库存
324 | private Stock checkStockWithRedis(int sid) throws Exception {
325 | Integer count = Integer.parseInt(RedisPoolUtil.get(RedisKeysConstant.STOCK_COUNT + sid));
326 | Integer sale = Integer.parseInt(RedisPoolUtil.get(RedisKeysConstant.STOCK_SALE + sid));
327 | Integer version = Integer.parseInt(RedisPoolUtil.get(RedisKeysConstant.STOCK_VERSION + sid));
328 | if (count < 1) {
329 | log.info("库存不足");
330 | throw new RuntimeException("库存不足 Redis currentCount: " + sale);
331 | }
332 | Stock stock = new Stock();
333 | stock.setId(sid);
334 | stock.setCount(count);
335 | stock.setSale(sale);
336 | stock.setVersion(version);
337 | // 此处应该是热更新,但是在数据库中只有一个商品,所以直接赋值
338 | stock.setName("手机");
339 |
340 | return stock;
341 | }
342 | // 更新 DB 和 Redis
343 | private void saleStockOptimsticWithRedis(Stock stock) throws Exception {
344 | int res = stockService.updateStockByOptimistic(stock);
345 | if (res == 0){
346 | throw new RuntimeException("并发更新库存失败") ;
347 | }
348 | // 更新 Redis
349 | StockWithRedis.updateStockWithRedis(stock);
350 | }
351 | // Redis 多个写入操作的事务
352 | public static void updateStockWithRedis(Stock stock) {
353 | Jedis jedis = null;
354 | try {
355 | jedis = RedisPool.getJedis();
356 | // 开始事务
357 | Transaction transaction = jedis.multi();
358 | // 事务操作
359 | RedisPoolUtil.decr(RedisKeysConstant.STOCK_COUNT + stock.getId());
360 | RedisPoolUtil.incr(RedisKeysConstant.STOCK_SALE + stock.getId());
361 | RedisPoolUtil.incr(RedisKeysConstant.STOCK_VERSION + stock.getId());
362 | // 结束事务
363 | List