`

并发访问的问题解决方案

阅读更多

目前正在做基于Red 5 的Meeting系统,我们会在Meeting server上生成一个唯一的StreamKey,用于RTMP协议中,NetStream.publish的StreamID,但是有一个问题,我们调用allocateStream的时候,如果一个会议中的多个成员并发请求这个服务时(Meeting server上生成一个唯一的StreamKey),会造成同一个meeting,使用不同的StreamID。

 

在单虚拟机的情况下,可以使用Synchronized原生锁来对同一个RoomKey进行加锁,如果reques的是同一个RoomKey,则需要排队处理,直到拿到这个StreamKey为止。

 

此例只适用于单JVM情况下的控制,如果在多虚拟机情况下,需要采用分布式锁的解决方案,可以用ZoomKeeper实现一个基于RoomKey的分布式锁逻辑,以后有空,会写出一个基于ZoomKeeper的分布式锁的版本。

 

注:此类并发问题,是经常会遇到的,写这篇blog,一方面提出解决方案,另外一方面希望初学者能够有所理解并注意并发访问而产生的问题

 

 

1.Class 1

package org.developerworks.test;

import UUIDGenerator;

import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * <p>Description:
 *
 * 这个类源自于一个需求:当并发访问时,同一个RoomKey对应只能生成一次UUID,
 * 因此需要把RoomKey作为一个对象锁,保证请求同一RoomKey锁的操作要进行同步(或者称为锁定)
 * 以保证同一个RoomKey只生成一个UUID
 *
 * 同步方法不能影响并发性(吞吐量),比如对于不同的RoomKey,并应该允许并发创建
 * 对于相同的RoomKey,应该锁定
 *
 * 此例关键点在于要使用RoomKey作为Synchronized的锁对象,已达到同一个RoomKey,采用排它锁,
 * 已避免同一个RoomKey生成了同多个StreamKey的作用
 *
 * </p>
 * <p>Copyright (c) 2010</p>
 * <p>Department: None</p>
 * <p>Company: None</p>
 * <p>Project:Test</p>
 *
 * @author Tomy Zhou
 * @since 1.0
 * @version org.developerworks.test; JoinServlet.java
 *         2010-7-26
 **/
public class JoinServlet extends HttpServlet{
   
    public static ConcurrentHashMap<String, String> map  = new ConcurrentHashMap(20);
   
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        String roomKey = req.getParameter("roomKey");
        RoomKeySingleton roomKeySingleton = RoomKeySingleton.getInstance(roomKey);
       
        String streamKey = null;
        String newUUID = null;
       
        //If the streamKey is not existed on the server, then create one.
        //If existed on the server, use the existed
        synchronized (roomKeySingleton) {
            if(map.get(roomKey)==null){
                System.out.println("Concurrent write="+roomKey);
                newUUID = UUIDGenerator.getUUID();   
                map.put(roomKey, newUUID);
                System.out.println("Concurrent write complete="+roomKey);
            }
        }
       
        resp.getWriter().println(roomKey+"-"+newUUID);
    }


}

 

 

2.Class 2

 

 

package org.developerworks.test;

import java.util.concurrent.ConcurrentHashMap;

/**
 * <p>Description: WeatherServer</p>
 * <p>Copyright (c) 2010</p>
 * <p>Department: None</p>
 * <p>Company: None</p>
 * <p>Project:WeatherServer</p>
 *
 * 此类用于为每个RoomKey建立一个单例的对象,对应来说,
 * 一个RoomKey对应唯一一个对象
 * @author Tomy Zhou
 * @since 1.0
 * @version org.developerworks.test; RoomKeySingleton.java
 *         2010-7-26
 **/
public class RoomKeySingleton {
    private static RoomKeySingleton roomKeySingleton;
    private static String roomKey;
    private static ConcurrentHashMap<String, RoomKeySingleton> map = new ConcurrentHashMap<String, RoomKeySingleton>();
   
    private RoomKeySingleton(String roomKey){
        this.roomKey = roomKey;
    }
   
    public static synchronized RoomKeySingleton getInstance(String roomKey){
        if(map.get(roomKey)==null){
            roomKeySingleton = new RoomKeySingleton(roomKey);
            map.put(roomKey, roomKeySingleton);
        }
       
        return map.get(roomKey);
    }

}

 

3. Class 3

 

package org.developerworks.test;
import java.util.UUID;

public class UUIDGenerator {
    public UUIDGenerator() {
    }
    /**
     * 获得一个UUID
     * @return String UUID
     */
    public static String getUUID(){
        String s = UUID.randomUUID().toString();
        //去掉“-”符号
        return s.substring(0,8)+s.substring(9,13)+s.substring(14,18)+s.substring(19,23)+s.substring(24);
    }
    /**
     * 获得指定数目的UUID
     * @param number int 需要获得的UUID数量
     * @return String[] UUID数组
     */
    public static String[] getUUID(int number){
        if(number < 1){
            return null;
        }
        String[] ss = new String[number];
        for(int i=0;i<number;i++){
            ss[i] = getUUID();
        }
        return ss;
    }
    public static void main(String[] args){
        String[] ss = getUUID(10);
        for(int i=0;i<ss.length;i++){
            System.out.println(ss[i]);
        }
    }
}

分享到:
评论

相关推荐

    阿里P8架构师谈:高并发架构解决方案总结

    高并发是指在同一个时间点,有很多用户同时访问URL地址,比如:淘宝的双11、双12,就会产生高并发。又如贴吧的爆吧,就是恶意的高并发请求,也就是DDOS攻击。服务端:导致站点服务器/DB服务器资源被占满崩溃,数据的...

    常见的提高高并发和高并发解决方案案例.txt

    常见的提高高并发下访问的效率的手段,了解高并发的的瓶颈在哪里,具体的高并发解决方案

    C#解决SQlite并发异常问题的方法(使用读写锁)

    本文实例讲述了C#解决SQlite并发异常问题的方法。分享给大家供大家参考,具体如下: 使用C#访问sqlite时,常会遇到多线程并发导致SQLITE数据库损坏的问题。 SQLite是文件级别的数据库,其锁也是文件级别的:多个线程...

    javaweb高并发量网站解决方案

    大型网站,比如门户网站,在面对大量用户访问、高并发请求方面,基本的解决方案集中在这样几个环节:使用高 性能的服务器、高性能的数据库、高效率的编程语言、还有高性能的Web容器。这几个解决思路在一定程度上意味...

    Java多线程并发访问解决方案

    NULL 博文链接:https://271072008-qq-com.iteye.com/blog/1086373

    提高IIS的并发访问量,达到十万的并发

    提高IIS的并发访问量,达到十万的并发

    IIS网站高性能高并发优化解决方案

    IIS网站高性能高并发优化解决方案,通过修改IIS配置结合window定时任务优化IIS下网站的高并发访问性能

    数据库访问的并发冲突与解决方法.doc

    数据库访问的并发冲突与解决方法

    ORACLE数据库并发访问控制机制及访问冲突的解决方法.pdf

    ORACLE数据库并发访问控制机制及访问冲突的解决方法.pdf

    java高并发解决方案

    在面对大量用户访问、高并发请求方面,基本的解决方案集中在这样几个环节:使用高性能的服务器、高性能的数据库、高效率的编程语言、还有高性能的Web容器。但是除了这几个方面,还没法根本解决大型网站面临的高负载...

    Redis高并发问题的解决方法

    由于单线程所以redis本身并没有锁的概念,多个客户端连接并不存在竞争关系,但是利用jedis等客户端对redis进行并发访问时会出现问题。发生连接超时、数据转换错误、阻塞、客户端关闭连接等问题,这些问题均是由于...

    大型网站应对高负载和并发的解决方案

    在面对大量用户访问、高并发请求方面,基本的解决方案集中在这样几个环节:使用高性能的服务器、高性能的数据库、高效率的编程语言、还有高性能的Web容器。但是除了这几个方面,还没法根本解决大型网站面临的高负载...

    微信小程序-控制微信小程序 wx.request 并发请求数量

    管理微信小程序 wx.request 方法的并发数,解决请求数大于 10 时,直接不请求的问题。如果需要 wx.request 方法支持 Promise,可以使用 wx-promise-request 库哦。 下载 由于小程序不支持 npm,所以直接右键保存 ...

    数据库并发操作

    数据库并发操作,悲观锁和乐观锁

    java并发访问重复请求过滤问题

    本篇文章给大家分享了关于java并发访问重复请求过滤的相关问题以及解决方法,对此有需要的朋友参考学习下。

    Web开发:解决网站高并发问题.docx

    在大型网站开发和设计过程中,非常需要考虑的问题是网站的并发访问的问题,为此我也通过思考,通过借鉴前辈们设计思想,总结出一些解决方案

    PHP高并发和大流量解决方案整理

    在互联网时代,并发,高并发通常是指并发访问。也就是在某个时间点,有多少个访问同时到来。 二、高并发架构相关概念 1、QPS (每秒查询率) : 每秒钟请求或者查询的数量,在互联网领域,指每秒响应请求数(指HTTP请求)...

    【文件夹】Go语言并发之道.pdf

    你将理解 Go语言为何选定这些并发模型,这些模型又会带来什么问题,以及你如何组合利用这些模型中的原语去解决问题。学习那些让你在独立且自信的编写与实现任何规模并发系统时所需要用到的技巧和工具。 理解Go语言...

    高性能电商秒杀解决方案

    高性能电商秒杀解决方案 秒杀的特点 • 大量用户在秒杀时间点发起购买请求,造成网站流量瞬间激增; • 秒杀的商品一般库存较少,只有少数用户能够购买,要控制好库存,防止超卖; • 整个系统关键在于支撑短时间内...

Global site tag (gtag.js) - Google Analytics