diff --git a/springAdvance/DistributionLock/SpringDistributionLock/README.md b/springAdvance/DistributionLock/SpringDistributionLock/README.md index 3637c8466..6f045535a 100644 --- a/springAdvance/DistributionLock/SpringDistributionLock/README.md +++ b/springAdvance/DistributionLock/SpringDistributionLock/README.md @@ -69,6 +69,9 @@ brew services start redis brew services stop redis +# reload nginx config +nginx -s reload + #--------------------------- # Intellij #--------------------------- diff --git a/springWarehouse/README.md b/springWarehouse/README.md index bbbfa03d0..1f2f4d8e7 100644 --- a/springWarehouse/README.md +++ b/springWarehouse/README.md @@ -18,6 +18,8 @@ ARCHITECTURE : - V1

+- V2 + - Cluster mode with Nginx [Demo](http://43.206.107.101:7777/) @@ -70,7 +72,41 @@ ARCHITECTURE : mvn package # run -java -jar target/springWarehouse-0.0.1-SNAPSHOT.jar +# https://blog.csdn.net/G971005287W/article/details/114879972 +java -jar target/springWarehouse-0.0.1-SNAPSHOT.jar --server.port=7777 +java -jar target/springWarehouse-0.0.1-SNAPSHOT.jar --server.port=7778 + +#--------------------------- +# Run nginx +#--------------------------- + +# https://github.com/yennanliu/utility_shell/blob/master/nginx/install_nginx.sh +# http://localhost:8080/ + +# start +brew services start nginx + +# stop +brew services stop nginx + + +#--------------------------- +# Other cmd +#--------------------------- + +# reload nginx config +nginx -s reload + +# kill progress uses port +lsof -i : +kill + +# pressure testing - jmeter +cd apache-jmeter-5.6.2 +bash bin/jmeter + +# curl +curl http://localhost:7777/productType/list?pageNoStr=1 ``` @@ -148,10 +184,15 @@ nohup java -jar target/springWarehouse-0.0.1-SNAPSHOT.jar & ## API -| API | Type | Purpose | Example cmd | Comment| -| ----- | -------- | ---- | ----- | ---- | -| http://localhost:7777/ | Get | Home page || | -| http://localhost:7777/swagger-ui/index.html | Get | API doc page || | +| API | Type | Purpose | Example cmd | Comment| +|-----------------------------------------------------|---------------| ---- | ----- | ---- | +| http://localhost:7777/ | Get | Home page || | +| http://localhost:7777/swagger-ui/index.html | Get | API doc page || | +| http://localhost:7777/test/type | test endpoint | | | +| http://localhost:7777/test/prod | test endpoint | | | +| http://localhost:7777/test/prod/deduct/{product_id} | test endpoint | | | +| http://localhost:8080/ | Nginx endpoint | | | + ## Important Concepts diff --git a/springWarehouse/nginx/nginx.conf b/springWarehouse/nginx/nginx.conf new file mode 100644 index 000000000..29189931c --- /dev/null +++ b/springWarehouse/nginx/nginx.conf @@ -0,0 +1,93 @@ + +# https://youtu.be/CDaWk2RIBL4?si=dfe4B7Ct4fsPSOGW&t=315 +# https://github.com/yennanliu/utility_shell/blob/master/nginx/nginx_backup.conf + +#user nobody; +worker_processes 1; + +#error_log logs/error.log; +#error_log logs/error.log notice; +#error_log logs/error.log info; + +#pid logs/nginx.pid; + + +events { + worker_connections 1024; +} + + +http { + include mime.types; + default_type application/octet-stream; + + #log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + # '$status $body_bytes_sent "$http_referer" ' + # '"$http_user_agent" "$http_x_forwarded_for"'; + + #access_log logs/access.log main; + + sendfile on; + #tcp_nopush on; + + #keepalive_timeout 0; + keepalive_timeout 65; + + #gzip on; + + # load balance, reverse proxy + # https://youtu.be/CDaWk2RIBL4?si=k5piBHOSF-7vNTh1&t=392 + upstream warehouseService { + server localhost:7777; + server localhost:7778; + } + + server { + listen 8080; + server_name localhost; + + location / { +# root html; +# index index.html index.htm; + proxy_pass http://warehouseService; + } + + } + + + # another virtual host using mix of IP-, name-, and port-based configuration + # + #server { + # listen 8000; + # listen somename:8080; + # server_name somename alias another.alias; + + # location / { + # root html; + # index index.html index.htm; + # } + #} + + + # HTTPS server + # + #server { + # listen 443 ssl; + # server_name localhost; + + # ssl_certificate cert.pem; + # ssl_certificate_key cert.key; + + # ssl_session_cache shared:SSL:1m; + # ssl_session_timeout 5m; + + # ssl_ciphers HIGH:!aNULL:!MD5; + # ssl_prefer_server_ciphers on; + + # location / { + # root html; + # index index.html index.htm; + # } + #} + include servers/*; +} \ No newline at end of file diff --git a/springWarehouse/sql/ddl/product.sql b/springWarehouse/sql/ddl/product.sql index a066db6c9..2ab442dbb 100644 --- a/springWarehouse/sql/ddl/product.sql +++ b/springWarehouse/sql/ddl/product.sql @@ -3,20 +3,25 @@ -- create database warehouse_system; +-- DROP TABLE product; + CREATE TABLE IF NOT EXISTS product( id int PRIMARY KEY AUTO_INCREMENT, name varchar(100) not null, - type_id int not null, + type_id int DEFAULT 1, price int not null, merchant_id varchar(100), product_status varchar(10), - amount int DEFAULT 0, - constraint FK_PRODUCT_TYPE FOREIGN KEY (type_id) references product_type(type_id) + amount int DEFAULT 0 + -- constraint FK_PRODUCT_TYPE FOREIGN KEY (type_id) references product_type(type_id) ); -- DML -INSERT INTO product(name, type_id, price, merchant_id, amount, product_status) +-- truncate product; + +INSERT INTO product(name, price, merchant_id, amount, product_status) VALUES -("i-phone", 2, 300, 1, 3, "on_board"), -("cookie2", 4, 10, 2, 2, "new"), -("soap", 1, 50, 1, 1, "off_board"); \ No newline at end of file +("i-phone", 300, 1, 5000, "on_board"), +("cookie2", 10, 2, 5000, "new"), +("soap", 50, 3, 5000, "off_board"), +("soap", 70, 4, 5000, "off_board"); \ No newline at end of file diff --git a/springWarehouse/src/main/java/com/yen/springWarehouse/controller/OrderController.java b/springWarehouse/src/main/java/com/yen/springWarehouse/controller/OrderController.java index 18b82ccbf..1b8a60b42 100644 --- a/springWarehouse/src/main/java/com/yen/springWarehouse/controller/OrderController.java +++ b/springWarehouse/src/main/java/com/yen/springWarehouse/controller/OrderController.java @@ -120,6 +120,7 @@ public String update(Order order) { */ @GetMapping(value="/download") public void download(){ + List orders = orderService.getAllOrders(); } diff --git a/springWarehouse/src/main/java/com/yen/springWarehouse/controller/TestController.java b/springWarehouse/src/main/java/com/yen/springWarehouse/controller/TestController.java new file mode 100644 index 000000000..63c021597 --- /dev/null +++ b/springWarehouse/src/main/java/com/yen/springWarehouse/controller/TestController.java @@ -0,0 +1,50 @@ +package com.yen.springWarehouse.controller; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.yen.springWarehouse.bean.Product; +import com.yen.springWarehouse.bean.ProductType; +import com.yen.springWarehouse.service.ProductService; +import com.yen.springWarehouse.service.ProductTypeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@RequestMapping("/test") +@RestController +public class TestController { + + @Autowired + ProductTypeService productTypeService; + + @Autowired + ProductService productService; + + + /** productType */ + @GetMapping("/type") + List getAllProductType(){ + + return productTypeService.list(new QueryWrapper<>()); + } + + + /** product */ + @GetMapping("/prod") + List getAllProduct(){ + + return productService.list(new QueryWrapper<>()); + } + + @GetMapping("/prod/deduct/{productId}") + String deductProduct(@PathVariable("productId") Integer productId){ + + productService.deduct(productId); + return "OK"; + } + +} diff --git a/springWarehouse/src/main/java/com/yen/springWarehouse/mapper/ProductMapper.java b/springWarehouse/src/main/java/com/yen/springWarehouse/mapper/ProductMapper.java index df4782459..20d9d0b7d 100644 --- a/springWarehouse/src/main/java/com/yen/springWarehouse/mapper/ProductMapper.java +++ b/springWarehouse/src/main/java/com/yen/springWarehouse/mapper/ProductMapper.java @@ -6,6 +6,7 @@ import com.yen.springWarehouse.bean.Product; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Update; import java.util.List; @@ -16,4 +17,6 @@ public interface ProductMapper extends BaseMapper { // TODO : check @Param("ew") ?? List getProductList(Page productPage, @Param("ew") Wrapper wrapper); + @Update("update product set amount = amount - #{amount} where id = #{productId} and amount >= #{amount}") + int updateProductCount(@Param("productId") Integer productId, @Param("amount") Integer amount); } diff --git a/springWarehouse/src/main/java/com/yen/springWarehouse/service/ProductService.java b/springWarehouse/src/main/java/com/yen/springWarehouse/service/ProductService.java index 376e32fb8..1b2ff7f3c 100644 --- a/springWarehouse/src/main/java/com/yen/springWarehouse/service/ProductService.java +++ b/springWarehouse/src/main/java/com/yen/springWarehouse/service/ProductService.java @@ -15,4 +15,5 @@ public interface ProductService extends IService { List getProductDtoListFromProductList(List productList); + void deduct(Integer id); } diff --git a/springWarehouse/src/main/java/com/yen/springWarehouse/service/impl/ProductServiceImpl.java b/springWarehouse/src/main/java/com/yen/springWarehouse/service/impl/ProductServiceImpl.java index 13e3e9ac3..b774b502d 100644 --- a/springWarehouse/src/main/java/com/yen/springWarehouse/service/impl/ProductServiceImpl.java +++ b/springWarehouse/src/main/java/com/yen/springWarehouse/service/impl/ProductServiceImpl.java @@ -1,6 +1,7 @@ package com.yen.springWarehouse.service.impl; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; @@ -30,6 +31,9 @@ public class ProductServiceImpl extends ServiceImpl impl @Autowired ProductTypeMapper productTypeMapper; + @Autowired + ProductMapper productMapper; + @Autowired MerchantService merchantService; @@ -94,4 +98,25 @@ public List getProductDtoListFromProductList(List productLi return productDtoList; } + @Override + public void deduct(Integer id) { + + /** V1 */ + System.out.println(">>> id = " + id); + Product product = productMapper.selectById(id); + System.out.println(">>> product = " + product); + int amount = product.getAmount(); + +// product.setAmount(amount-1); +// UpdateWrapper wrapper = new UpdateWrapper<>(product); +// // TODO : check why productMapper CAN'T update with UpdateWrapper +// //productMapper.update(product, wrapper); //baseMapper.update(product, wrapper); +// productMapper.updateById(product); + + /** V2 : use Mysql lock deal with cluster deployment */ + + productMapper.updateProductCount(product.getId(), 1); + System.out.println(">>> product = " + product); + } + } diff --git a/springWarehouse/src/main/resources/application.properties b/springWarehouse/src/main/resources/application.properties index 2211bf3ad..815379fcc 100644 --- a/springWarehouse/src/main/resources/application.properties +++ b/springWarehouse/src/main/resources/application.properties @@ -4,11 +4,11 @@ debug=true server.tomcat.uri-encoding=UTF-8 spring-http-encoding.charset=UTF-8 # hot deployment -spring.devtools.restart.enabled=true -spring.thymeleaf.mode=HTML5 -spring.thymeleaf.encoding=UTF-8 -spring.thymeleaf.cache=false -spring.thymeleaf.suffix=.html +#spring.devtools.restart.enabled=true +#spring.thymeleaf.mode=HTML5 +#spring.thymeleaf.encoding=UTF-8 +#spring.thymeleaf.cache=false +#spring.thymeleaf.suffix=.html # mysql spring.datasource.url=jdbc:mysql://localhost:3306/warehouse_system?createDatabaseIfNotExist=true