日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長(zhǎng)提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢(xún)客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

倉(cāng)庫(kù)地址:https://gitee.com/J_look/ssm-zookeeper/blob/master/README.md

  • 鎖:我們?cè)诙嗑€程中接觸過(guò),作用就是讓當(dāng)前的資源不會(huì)被其他線程訪問(wèn)!
    我的日記本,不可以被別人看到。所以要鎖在保險(xiǎn)柜中當(dāng)我打開(kāi)鎖,將日記本拿走了,別人才能使用這個(gè)保險(xiǎn)柜
  • 在zookeeper中使用傳統(tǒng)的鎖引發(fā)的 “羊群效應(yīng)” :1000個(gè)人創(chuàng)建節(jié)點(diǎn),只有一個(gè)人能成功,999
    人需要等待!
  • 羊群是一種很散亂的組織,平時(shí)在一起也是盲目地左沖右撞,但一旦有一只頭羊動(dòng)起來(lái),其他的羊
    也會(huì)不假思索地一哄而上,全然不顧旁邊可能有的狼和不遠(yuǎn)處更好的草。羊群效應(yīng)就是比喻人都有一種從眾心理,從眾心理很容易導(dǎo)致盲從,而盲從往往會(huì)陷入騙局或遭到失敗。

實(shí)現(xiàn)分布式鎖的大致流程

阿里3個(gè)小時(shí)手把手教你用zookeeper實(shí)現(xiàn)分布式鎖

 

整體思路

阿里3個(gè)小時(shí)手把手教你用zookeeper實(shí)現(xiàn)分布式鎖

 

  1. 所有請(qǐng)求進(jìn)來(lái),在/lock下創(chuàng)建 臨時(shí)順序節(jié)點(diǎn) ,放心,zookeeper會(huì)幫你編號(hào)排序
  2. 判斷自己是不是/lock下最小的節(jié)點(diǎn)
  3. 是,獲得鎖(創(chuàng)建節(jié)點(diǎn))
  4. 否則,對(duì)前面小我一級(jí)的節(jié)點(diǎn)進(jìn)行監(jiān)聽(tīng)
  5. 獲得鎖請(qǐng)求,處理完業(yè)務(wù)邏輯,釋放鎖(刪除節(jié)點(diǎn)),后一個(gè)節(jié)點(diǎn)得到通知(比你年輕的死了,你
    成為最嫩的了)
  6. 重復(fù)步驟2

安裝Nginx

安裝nginx運(yùn)行所需的庫(kù)

bash

//一鍵安裝上面四個(gè)依賴(lài)
yum -y install gcc zlib zlib-devel pcre-devel openssl openssl-devel

下載nginx

在那個(gè)目錄下執(zhí)行這個(gè)命令 就會(huì)下載到哪個(gè)目錄下

bash

//下載tar包
wget http://nginx.org/download/nginx-1.13.7.tar.gz

解壓

注意哦 解壓出來(lái)的文件 我們還需要安裝哦

下面所有的命令 都是在nginx-1.13.7文件夾里面進(jìn)行哦

highlighter-

tar -zxvf  nginx-1.13.7.tar.gz
  • 查看解壓出來(lái)的文件
  • highlighter-
  • ll ./nginx-1.13.7
  •  

安裝

創(chuàng)建一個(gè)文件夾,也就是nginx需要安裝到的位置

bash

mkdir /usr/local/nginx

執(zhí)行命令 考慮到后續(xù)安裝ssl證書(shū) 添加兩個(gè)模塊

bash

./configure --with-http_stub_status_module --with-http_ssl_module

執(zhí)行make install命令

bash

make install
  • 我們可以來(lái)到nginx安裝到的目錄下查看
  • 你們沒(méi)有我這么多目錄 conf 配置 sbin 啟動(dòng)nginx
  • 博主技術(shù)有限,還沒(méi)有深入去學(xué)習(xí)nginx的 大致這樣介紹吧
  •  

啟動(dòng)nginx服務(wù)

我這個(gè)是在/ 目錄底下執(zhí)行的 你們可以根據(jù) 自己所在的目錄去執(zhí)行

bash

 /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf

訪問(wèn)nginx

nginx的默認(rèn)端口是80

配置nginx

我們所做的配置大概就是

當(dāng)有人請(qǐng)求去訪問(wèn)我們服務(wù)器,然后負(fù)載到我們處理請(qǐng)求的服務(wù)器 我這里是為了方便 處理請(qǐng)求的這兩臺(tái)服務(wù)器 是在我windows上

打開(kāi)配置文件

bash

# 打開(kāi)配置文件
vim /usr/local/nginx/conf/nginx.conf
  • 圖中 紅框的位置 是需要添加的內(nèi)容
  • 配置含義: 我們的nginx監(jiān)聽(tīng)的是服務(wù)器的80端口 當(dāng)有請(qǐng)求訪問(wèn)時(shí) 會(huì)負(fù)載到 look代理里面 server是處理請(qǐng)求的兩臺(tái)服務(wù)器
  • 查看本機(jī)ip Windows ==>ipconfig linux ==> ip a(ip address)
阿里3個(gè)小時(shí)手把手教你用zookeeper實(shí)現(xiàn)分布式鎖

 

xml

upstream look{ 
    server 192.168.204.1:8001; //192.168.204.1是我本機(jī)的ip地址,8001是Tomcat的端口號(hào)
    server 192.168.204.1:8002; //8002是另外一個(gè)工程的tomcat端口號(hào)
}
server { 
	listen 80; 
	server_name localhost; 
	#charset koi8-r; 
	#access_log logs/host.access.log main; 
	location / {
		proxy_pass http://look; 
		root html; 
	index index.html index.htm; 
}

工程的搭建

搭建ssm框架 有時(shí)間推出springboot的版本

  • 創(chuàng)建一個(gè)maven項(xiàng)目(普通maven項(xiàng)目即可)

創(chuàng)建數(shù)據(jù)庫(kù):

sql

-- 商品表
create table product(
id int primary key auto_increment, -- 商品編號(hào)
product_name varchar(20) not null, -- 商品名稱(chēng)
stock int not null, -- 庫(kù)存
version int not null -- 版本
)
insert into product (product_name,stock,version) values('錦鯉-清空購(gòu)物車(chē)-大獎(jiǎng)',5,0)

sql

-- 訂單表
create table `order`(
id varchar(100) primary key, -- 訂單編號(hào)
pid int not null, -- 商品編號(hào)
userid int not null -- 用戶(hù)編號(hào)
)
  • 項(xiàng)目目錄結(jié)構(gòu)

添加依賴(lài)

簡(jiǎn)單解釋一下build

我們引入的是tomcat7的插件configuration 配置的是端口 和根目錄注意哦 記得刷新pom文件 build里面會(huì)有爆紅 不要緊張 不用管他 后面的配置他會(huì)自己消失

xml

<properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <spring.version>5.2.7.RELEASE</spring.version>
    </properties>

<packaging>war</packaging>

    <dependencies>
        <!-- Spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!-- MyBatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.10</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>2.0.7</version>
        </dependency>
        <!-- 連接池 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.11</version>
        </dependency>
        <!-- 數(shù)據(jù)庫(kù) -->
        <dependency>
            <groupId>MySQL</groupId>
            <artifactId>mysql-connector-JAVA</artifactId>
            <version>8.0.29</version>
        </dependency>
        <!-- junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.24</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <!-- maven內(nèi)嵌的tomcat插件 -->
            <plugin>
                <groupId>org.Apache.tomcat.maven</groupId>
                <!-- 目前apache只提供了tomcat6和tomcat7兩個(gè)插件 -->
                <artifactId>tomcat7-maven-plugin</artifactId>
                <configuration>
                    <port>8002</port>
                    <path>/</path>
                </configuration>
                <executions>
                    <execution>
                        <!-- 打包完成后,運(yùn)行服務(wù) -->
                        <phase>package</phase>
                        <goals>
                            <goal>run</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
折疊 

mybatis.xml

注意哦 :仔細(xì)查看上面的項(xiàng)目結(jié)構(gòu) 創(chuàng)建相應(yīng)的文件夾

xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!-- 后臺(tái)的日志輸出  輸出到控制臺(tái)-->
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>
</configuration>

spring.xml

注意哦 :仔細(xì)查看上面的項(xiàng)目結(jié)構(gòu) 創(chuàng)建相應(yīng)的文件夾

xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!-- 1.掃描包下的注解 -->
    <context:component-scan base-package="controller,service,mApper"/>
    <!-- 2.創(chuàng)建數(shù)據(jù)連接池對(duì)象 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
          destroy-method="close">
        <property name="url" value="jdbc:mysql://localhost:3306/2022_zkproduct?serverTimezone=GMT"/>
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="username" value="root"/>
        <property name="password" value="317311"/>
        <property name="maxActive" value="10"/>
        <property name="minIdle" value="5"/>
    </bean>

    <!-- 3.創(chuàng)建SqlSessionFactory,并引入數(shù)據(jù)源對(duì)象 -->
    <bean id="sqlSessionFactory"
          class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <property name="configLocation" value="classpath:mybatis/mybatis.xml"></property>
    </bean>

    <!-- 4.告訴spring容器,數(shù)據(jù)庫(kù)語(yǔ)句代碼在哪個(gè)文件中-->
    <!-- mapper.xDao接口對(duì)應(yīng)resources/mapper/xDao.xml-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="mapper"></property>
    </bean>

    <!-- 5.將數(shù)據(jù)源關(guān)聯(lián)到事務(wù) -->
    <bean id="transactionManager"
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!-- 6.開(kāi)啟事務(wù) -->
    <tx:annotation-driven/>
</beans>

折疊 

web.xml

注意哦 :仔細(xì)查看上面的項(xiàng)目結(jié)構(gòu) 創(chuàng)建相應(yīng)的文件夾

這里也會(huì)出現(xiàn)爆紅,后面會(huì)自己消失

xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
    <servlet>
        <servlet-name>springMVC</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring/spring.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
        <async-supported>true</async-supported>
    </servlet>

    <servlet-mapping>
        <servlet-name>springMVC</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

實(shí)體類(lèi)

  • @Data 是lombok的注解

Product

java

/**
 * @author : look-word
 * 2022-07-17 10:12
 **/
@Data
public class Product implements Serializable {
    private Integer id;
    private String product_name;
    private Integer stock;
    private Integer version;
}

Order

highlighter- php

/**
 * @author : look-word
 * 2022-07-17 10:12
 **/
@Data
public class Order implements Serializable {
    private String id;
    private Integer pid;
    private Integer userid;
}

持久層

ProductMapper

java

@Mapper
@Component
public interface ProductMapper {
    // 查詢(xún)商品(目的查庫(kù)存)
    @Select("select * from product where id = #{id}")
    Product getProduct(@Param("id") int id);

    // 減庫(kù)存
    @Update("update product set stock = stock-1 where id = #{id}")
    int reduceStock(@Param("id") int id);
}

OrderMapper

java

@Mapper
@Component
public interface OrderMapper {
    // 生成訂單
    @Insert("insert into `order` (id,pid,userid) values (#{id},#{pid},#{userid})")
    int insert(Order order);
}

service

ProductService

java

/**
 * @author : look-word
 * 2022-07-17 10:28
 **/
public interface ProductService {
    // 扣除庫(kù)存
    void reduceStock(Integer id) throws Exception;
}

ProductServiceImpl

java

/**
 * @author : look-word
 * 2022-07-17 10:29
 **/
@Transactional
@Service
public class ProductServiceImpl implements ProductService {
    @Resource
    private ProductMapper productMapper;

    @Resource
    private OrderMapper orderMapper;
	
    @Override
    public void reduceStock(Integer id) throws Exception {
        // 查詢(xún)商品庫(kù)存
        Product product = productMapper.getProduct(id);
        if (product.getStock() <= 0) {
            throw new RuntimeException("庫(kù)存不足");
        }
        // 減庫(kù)存
        int i = productMapper.reduceStock(id);
       
        if (i == 1) {
            Order order = new Order();
            order.setId(UUID.randomUUID().toString());
            order.setUserid(1);
            order.setPid(id);
            Thread.sleep(500);
            orderMapper.insert(order);
        } else {
            throw new RuntimeException("扣除庫(kù)存失敗");
        }
    }
}

controller

java

/**
 * @author : look-word
 * 2022-07-17 10:12
 **/
@RestController
public class ProductAction {

    @Resource
    private ProductService productService;
    
    @GetMapping("product/reduce/{id}")
    private Object reduce(@PathVariable Integer id) throws Exception {
        productService.reduceStock(id);
        return "ok";
    }
}

啟動(dòng)測(cè)試

  • 點(diǎn)擊右側(cè)的maven

還記得我們?cè)趐om.xml配置的tomcat的插件嗎,我們配置的意思是打包(package)之后會(huì)自動(dòng)運(yùn)行

在執(zhí)行打包命令之前,先執(zhí)行clean命令
執(zhí)行package命令

測(cè)試

  • 瀏覽器訪問(wèn)

highlighter- Go

http://localhost:8001/product/reduce/1
阿里3個(gè)小時(shí)手把手教你用zookeeper實(shí)現(xiàn)分布式鎖

 

訪問(wèn)流程

阿里3個(gè)小時(shí)手把手教你用zookeeper實(shí)現(xiàn)分布式鎖

 

**注意**

在使用jmeter測(cè)試的時(shí)候 需要啟動(dòng)兩個(gè)服務(wù)

  • 在啟動(dòng)第一個(gè)之后 去修改pom里面的build里面tomcat插件的端口 8002
  • 記得要刷新pom文件,然后再打包啟動(dòng)即可

啟動(dòng)jmeter測(cè)試

簡(jiǎn)單闡述一下:我們會(huì)模擬高并發(fā)場(chǎng)景下對(duì)這個(gè)商品的庫(kù)存進(jìn)行扣減

這也就會(huì)導(dǎo)致一個(gè)問(wèn)題,會(huì)出現(xiàn)商品超賣(mài)(出現(xiàn)負(fù)的庫(kù)存)出現(xiàn)的原因: 在同一時(shí)間,訪問(wèn)的請(qǐng)求很多。

下載地址

解壓雙擊jmeter.bat啟動(dòng)

阿里3個(gè)小時(shí)手把手教你用zookeeper實(shí)現(xiàn)分布式鎖

 

創(chuàng)建線程組

阿里3個(gè)小時(shí)手把手教你用zookeeper實(shí)現(xiàn)分布式鎖

 

這里的線程數(shù)量根據(jù)自己電腦去設(shè)置

創(chuàng)建請(qǐng)求

阿里3個(gè)小時(shí)手把手教你用zookeeper實(shí)現(xiàn)分布式鎖

 

我們填寫(xiě)紅框的內(nèi)容即可就是訪問(wèn)的地址

  • 我們還需要查看請(qǐng)求的結(jié)果 創(chuàng)建結(jié)果樹(shù) 右擊會(huì)出現(xiàn)
阿里3個(gè)小時(shí)手把手教你用zookeeper實(shí)現(xiàn)分布式鎖

 

配置好這些之后,點(diǎn)擊菜單欄綠色啟動(dòng)標(biāo)志

  • 會(huì)出現(xiàn)彈窗 第一個(gè)點(diǎn)yes 第二個(gè)點(diǎn)cancel(取消)

去數(shù)據(jù)庫(kù)查看

  • 沒(méi)有啟動(dòng)前數(shù)據(jù)庫(kù)的庫(kù)存
  • 可以看到 出現(xiàn)了 超賣(mài)
阿里3個(gè)小時(shí)手把手教你用zookeeper實(shí)現(xiàn)分布式鎖

 

解決超賣(mài)

需要用到 zookeeper集群,搭建的文章

zookeeper分布式鎖不需要我們手寫(xiě)去實(shí)現(xiàn),有封裝好的依賴(lài),引入即可

xml

<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-recipes</artifactId>
    <version>4.2.0</version> <!-- 網(wǎng)友投票最牛逼版本 -->
</dependency>

在控制層中加入分布式鎖的邏輯代碼

  • 添加了集群的ip

java

/**
 * @author : look-word
 * 2022-07-17 10:12
 **/
@RestController
public class ProductAction {

    @Resource
    private ProductService productService;
    // 集群ip
    private String connectString = "192.168.77.132,192.168.77.131,192.168.77.130";


    @GetMapping("product/reduce/{id}")
    private Object reduce(@PathVariable Integer id) throws Exception {
        // 重試策略 (1000毫秒試1次,最多試3次)
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
        //1.創(chuàng)建curator工具對(duì)象
        CuratorFramework client = CuratorFrameworkFactory.newClient(connectString, retryPolicy);
        client.start();
        //2.根據(jù)工具對(duì)象創(chuàng)建“內(nèi)部互斥鎖”
        InterProcessMutex lock = new InterProcessMutex(client, "/product_" + id);
        try {
            //3.加鎖
            lock.acquire();
            productService.reduceStock(id);
        } catch (Exception e) {
            if (e instanceof RuntimeException) {
                throw e;
            }
        } finally {
            //4.釋放鎖
            lock.release();
        }
        return "ok";
    }
}

啟動(dòng)jmeter去測(cè)試,會(huì)發(fā)現(xiàn),請(qǐng)求就像排隊(duì)一樣,一個(gè)一個(gè)出現(xiàn),數(shù)據(jù)庫(kù)也沒(méi)有超賣(mài)現(xiàn)象

  • 可以看到 只有前面的5課請(qǐng)求成功了,我們的庫(kù)存只有5個(gè)
  • 說(shuō)明我們的分布式鎖,已經(jīng)實(shí)現(xiàn)了
  •  

springboot版本后續(xù)會(huì)退出

原文鏈接:
https://www.cnblogs.com/look-word/p/16488623.html

分享到:
標(biāo)簽:zookeeper
用戶(hù)無(wú)頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過(guò)答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫(kù),初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定