精华内容
下载资源
问答
  • 当我们聊IO底层原理的时候我们应该想到哪些关键问题节点? 用户进程进行IO读写,对应操作系统内核(kernel)底层的IO的read/write必然区分,是否是物理设备直接的读写?(必然不是)? 用户进程...

     

    业务高并发离不开,Netty\Redis\Zookeeper等分布式高性能工具,涉及到高并发肯定离不开频繁的IO读写操作,IO底层原理是这些高并发工具的一个基石;

    IO的底层原理

    当我们聊IO底层原理的时候我们应该想到哪些关键问题节点?

    • 用户进程进行IO读写,对应操作系统内核(kernel)底层的IO的read/write必然有区分,是否是物理设备直接的读写?(必然不是)?
    • 用户进程、系统内核 进行read、write操作是缓冲区起到了什么作用?
    • 4种IO模型的流程?(同步阻塞、同步非阻塞、IO多路复用、异步IO)
    • IO阻塞过程,cup执行的内核态用户态是如何进行切换的?(参考:CPU用户态和内核态)
    • Java NIO的IO模型(io多路复用)?三个组件(channel、buffer、selector)?NIO在网络通信中的应用?
    • Reactor反应器主要是用来解决什问题而产生的(Java OIO 网络通信阻塞式的等待连接,进而引入的一连接一线程,但资源消耗严重)?该模型如何应用到Netty框架的?

    基于这些问题go on;

    内核缓存区和进程缓冲区

    首先我们应该明白一点就是在进行一次read/write(后续rw简写)系统调用或socket套接字调用,并不是直接进行物理设备和内存之间的数据置换;他们都是通过一层缓冲区进行数据置换的;

    • 调用操作系统的read,是把数据从系统内核缓冲区复制到进程缓冲区;而w调用是把数据从进程缓冲区复制到内核缓存区;

    • 调用socket套接字的r,是把数据从系统内核缓冲区复制到网卡(这里我理解网卡类似用户进程缓冲区);而w调用是把数据从网卡复制到内核缓存区;
    • 无论是socket的IO,还是文件的IO都是上层应用的开发,他们属于输入Input和输出Output,在编程流程上都是一致的;

    为何要设置这么多的缓存区呢?

    缓存区的目的是为了减少频繁的与设备之间的物理交换,我们清楚外部物理设备的直接读写,涉及到操作系统的中断。发生中断时要保留进程的数据和状态信息,而结束中断后要恢复。为了减少这种中断带来底层系统的时间和性能损耗,于是出现了内存缓冲区;

    有了内核缓冲区,操作系统会对内核缓存区进行监控,等待缓存区数据达到一定大小时,才进行IO设备的中断处理,集中执行物理设备的IO操作,这种机制提升系统性能;用户进程缓存区,则是将用户进程的IO操作集中处理;用户进程的IO操作实际上是用户进程缓存区和内核缓冲区之间的数据置换;

    系统调用read&write流程

    read一个socket套接字的流程如下:

    • 客户端请求:Linux通过网卡读取客户端的请求数据,将数据读取到内核缓存区
    • 获取数据请求:java服务器通过read调用,从linux内核缓冲区读取数据,再送入到java进程缓冲区。
    • 服务器端业务处理:java服务器在自己的用户空间处理客户端的请求。
    • 服务器端返回数据:java服务器完成处理后,通过系统write调用,将数据从系统内核缓冲区写入到用户缓冲区。
    • 发送数据给客户端:系统内核通过网络IO,将内核缓冲区数据写入到网卡,网卡通过底层通信协议将数据发送给目标客户端;

    四种主流的IO通信模型

    同步阻塞IO(Blocking IO)

    优点:程序开发简单,阻塞等待数据期间,用户线程挂起;阻塞期间,用户线程基本不会占用CPU;

    缺点:每个连接会开启一个独立线程,维护一个连接的IO;并发量高的情况下,维护大量的网络连接,内存、线程切换开销巨大;不适合高并发。

    同步非租塞IO(None Blocking IO)

    优点:每次发起IO系统调用,在内核等待数据过程中可以立即返回。用户线程并不会阻塞,实时性好;

    缺点:用户进程要想拿到数据,需要不断轮询,这将占用大量cpu;这里的同步非租塞IO不是java的NIO(NIO采用的IO多路复用);

    IO多路复用(IO Multiplexing)

    查询IO数据就绪状态的轮询过程交给了select/epoll调用完成,通过这种调用方式,一个进程可以监视多个文件描述符(文件句柄),一旦某个文件描述符数据准备就绪(内核缓存区可读、写),内核就将就绪的状态返回给用户进程,随后用户程序进行就绪状态数据的IO rw系统调用;与NIO模型相比,IO多路复用模型涉及两种系统调用,一种是select/epoll(就绪查询),另一种是IO操作;NIO只有IO操作;

    流程:

    • 选择器注册:read操作的目标socket网络连接,提前注册到select/epoll选择器中,Java对应Selector类。
    • 就绪状态轮询:用户进程通过调用选择器的查询方法,查询注册过的所有socket连接的就绪状态。查询方法内核会返回一个socket的就绪列表;当任何一个注册过的socket中的数据准备好了,内核缓存区有数据了,内核将就绪socket加入到就绪列表返回;调用select查询是整个线程是阻塞的;
    • 用户线程就绪socket列表,进行socket的read系统调用,用户线程阻塞,内核复制数据到用户缓存区;
    • 用户线程解除阻塞,执行后续流程;

    优点:与一个线程维护一个连接的阻塞IO模式相比,使用select/epoll的最大优势在于,一个选择器查询线程可以同时处理成千上万个连接。系统不必创建大量的线程,也不必维护这些线程,大大减小系统开销;

    缺点:本质上select/epoll系统调用是阻塞式的,属于同步IO。都需要在读写事件就绪后,由系统调用本身负责进行读写,这个读写过程是阻塞的。

    异步IO(Asynchronous IO)

    用户线程通过系统调用,向内核注册某个IO操作。内核在整个IO操作(从网卡读取数据到内核缓冲区、数据复制到用户缓冲区)完成后,通知用户程序,用户程序执行后续业务操作;内核的整个IO操作过程中用户程序不阻塞;

    优点:在内核等待数据和复制两个阶段,用户线程都不阻塞。用户线程接收内核IO操作完成的事件,或者用户线程需要注册一个IO操作完成的回调函数。吞吐量最大;

    缺点:应用程序需要进行事件注册和接收,其余工作交给系统内核,底层系统内核需要支持;Linux 2.6版本才引入异步IO,目前不完善。

    Java NIO 通信详解

            之前就说了java NIO是基础IO多路复用模型进行通信的,New IO也有人称为非阻塞IO(Non-Block IO),弥补了老式IO(OIO)面向流阻塞的不足,它是面向缓冲区的;Java NIO被应用到文件读写和网络通信中;

    提供了三个核心组件:

    • Channel(通道):同一个网络连接关联的两个流的结合体,既可以从通道读取,也可以向通道写入;4种channel(FileChannel(不能设置非租塞模式),SocketChannel.ServerSocketChannel,DataGrameChannel)
    • Buffer(缓冲区):读取和写入只需要从通道中将数据rw到缓冲区,可以随便一读取buffer的任何位置;8种数据类型(ByteBuffer、CharBuffer、DoubleBuffer、FloatBuffer、IntBuffer、LongBuffer、ShortBuffer、MappedBuffer),3个重要属性(capacity\position\limit);
    • Selector(选择器):实现IO多路复用的关键,首先把通道注册到选择器中,选择器提供select方法进行select/epoll的系统调用,查询注册的通道是否有就绪的IO事件(选择键)(可读、可写、网络连接完成);

    与Java OIO相比,java NIO网络通信编程特点大致如下:

    (1)、在NIO中,服务器接收新连接的工作,是异步进行的。不像java的OIO那样,服务器监听连接是同步、阻塞的。NIO可以通过选择器(多路复用器)查看IO事件的就绪状态,后续只需不断进行轮询选择器中的选择键集合,选择新到来的连接;

    (2)、NIO中SocketChannel通道的读写操作都是异步的。如果没有可读写的数据,负责IO的线程不会阻塞同步等待,线程可以处理其他的连接通道;

    (3)、NIO中选择器可以同时处理成千上万个客户端连接,性能会随着客户端的增加而线性下降;

    Reactor反应器模式

    现状:高并发通信中间件Netty、Nginx、Redis等都是基于Reactor反应器模式实现的;

    背景:在Reactor反应器模式出现之前;Java 原始的OIO编程,网络服务器程序,是通过一个while循环,不断的监听端口是否有新的连接。如果有才调用处理函数处理。示例代码

    while(true){
        socket=accept(); //阻塞,接收连接
        hadler(socket);  //读取数据,业务处理,写入结果
    }

    这种方法问题在一个连接handler(socket) 没有处理完,那么后面的连接请求没法被接收,于是后面的请求统统会被阻塞住,服务器的吞吐量就太低了。

    进而引入了Connection Per Thread(一线程处理一连接)模式。代码逻辑如下:

    class ConnectionPerThread implements Runnable{
        public void run(){
            try{
                ServerSocket serverSocket=new ServerSocket(SOCKET_SERVER_PORT);   
                while(!Thread.interrupted()){
                    Socket socket = serverSocket.accept();
                    //接收一个连接后,为socket连接,新建一个专属的处理器对象
                    Handler handler=new Handler(socket);
                    //创建新线程专门处理这个连接
                    new Thread(handler).start();
                } 
            }catch(Exception e){
                //异常处理
            }
        }
    }
    
    static class Handler implements Runnable{
        final Socket socket;
        Handler(Socket s){
           this.socket=s;
        }
        while(true){
            try{
                byte[] input=new byte[1024];
                //读取数据源
                socket.getInputStream().read(input);
                //业务逻辑处理
                ....
                byte[] output=null;
                //写入结果
                socket.getOutputStream().write(outPut);
            }catch(Exception e){
                //异常处理
            }
        }
    }

    解决了前面新连接被严重阻塞的问题,在一定程度上,极大提高了服务器的吞吐量;但是对于成千上万的连接,需要耗费大量线程资源(创建、销毁、线程切换代价太高);所以引入了Reactor反应器模式,对线程数据量进行控制,做到一个线程可以处理大量的连接;

    反应器模式Reactor由反应器线程、Handler处理器两大角色组成:

    • Reactor反应器职责:负责查询IO事件,就是检查NIO中注册到选择器上的IO事件(读、写、连接建立、连接接受),并分发到Handlers处理器。
    • Handlers处理器的职责:与IO事件(或者叫选择键)绑定,非阻塞的处理IO事件,执行真正建立连接、通道数据读取、业务处理逻辑、写入到通道等。

    单线程的Reactor反应器模式

    Reactor选择器需要用到SelectionKey提供的两个方法:

    • 一个void attach(Object o) 方法,将处理器作为附件绑定到选择键(或者叫做事件)上;
    • 另一个方法Object attachment() ,可以从选择键上获取到绑定handler处理器;

    通信服务端的Reactor反应器和处理器在同一个线程中:

    单线程Reactor模型

    public class Reactor implements Runnable {  
            private final ServerSocketChannel ssc;  
            private final Selector selector;  
          
            public TCPReactor(int port) throws IOException {  
                selector = Selector.open();  
                ssc = ServerSocketChannel.open();  
                InetSocketAddress addr = new InetSocketAddress(port);  
                // 在ServerSocketChannel绑定监听端口
                ssc.socket().bind(addr); 
                // 设置ServerSocketChannel为非阻塞  
                ssc.configureBlocking(false); 
                // ServerSocketChannel向selector注册一个OP_ACCEPT事件,然后返回通道的key 
                SelectionKey sk = ssc.register(selector, SelectionKey.OP_ACCEPT);
                // 核心1:给选择key绑定一个附加的Acceptor处理器    
                sk.attach(new Acceptor(selector, ssc));
            }  
          
            @Override  
            public void run() {  
                // 在线程被中断前持续运行  
                while (!Thread.interrupted()) {
                    System.out.println("Waiting for new event on port:"+ssc.socket().getLocalPort() + "...");  
                    try {  
                        // 若沒有事件就就绪则不往下执行 
                        if (selector.select() == 0) 
                            continue;  
                    } catch (IOException e) {  
                        // TODO Auto-generated catch block  
                        e.printStackTrace();  
                    }  
                    // 取得所有已就绪事件的key集合  
                    Set<SelectionKey> selectedKeys = selector.selectedKeys(); 
                    Iterator<SelectionKey> it = selectedKeys.iterator();  
                    while (it.hasNext()) {  
                        // 根據事件的key進行調度  
                        dispatch((SelectionKey) (it.next()));
                        // 处理完后从就绪事件列表中移除
                        it.remove();  
                    }  
                }  
            }  
          
            /* 
             * name: dispatch(SelectionKey key) 
             * description: 調度方法,根據事件绑定的对象新开线程 
             */  
            private void dispatch(SelectionKey key) {  
                // 核心2:根据事件之key绑定的对象新开线程
                Runnable r = (Runnable) (key.attachment());   
                if (r != null)  
                    r.run();  
           }
    
           
           class AcceptorHandler implements Runnable {  
          
                private final ServerSocketChannel ssc;  
                private final Selector selector;  
                // 核心3:使用同一个选择器注册其他事件
                public Acceptor(Selector selector, ServerSocketChannel ssc) {  
                    this.ssc=ssc;  
                    this.selector=selector;  
                }  
              
                @Override  
                public void run() {  
                    try { 
                        // 接受client连接请求  
                        SocketChannel sc= ssc.accept();  
                     System.out.println(sc.socket().getRemoteSocketAddress().toString() + " is connected.");  
                      
                    if(sc!=null) {  
                        // 设置为非阻塞  
                        sc.configureBlocking(false);
                        // SocketChannel向selector注册一个OP_READ事件,然后返回该通道的key
                        SelectionKey sk = sc.register(selector, SelectionKey.OP_READ);   
                        // 使一个阻塞住的selector操作立即返回
                        selector.wakeup();  
                        // 给定key一个附加的IOHandler处理象  
                        sk.attach(new IOHandler(sk, sc));
                    }  
                      
                } catch (IOException e) {  
                    // TODO Auto-generated catch block  
                    e.printStackTrace();  
                }  
            }  
        }
    
    
    
        class IOHandler implements Runnable {  
          
            private final SelectionKey sk;  
            private final SocketChannel sc;  
          
            int state;   
          
            public TCPHandler(SelectionKey sk, SocketChannel sc) {  
                this.sk = sk;  
                this.sc = sc;  
                state = 0; // 初始狀態設定為READING  
            }  
          
            @Override  
            public void run() {  
                try {  
                    if (state == 0)  
                        read(); // 讀取網絡數據  
                    else  
                        send(); // 發送網絡數據  
          
                } catch (IOException e) {  
                    System.out.println("[Warning!] A client has been closed.");  
                    closeChannel();  
                }  
            }  
              
            private void closeChannel() {  
                try {  
                    sk.cancel();  
                    sc.close();  
                } catch (IOException e1) {  
                    e1.printStackTrace();  
                }  
            }  
          
            private synchronized void read() throws IOException {  
                // non-blocking下不可用Readers,因為Readers不支援non-blocking  
                byte[] arr = new byte[1024];  
                ByteBuffer buf = ByteBuffer.wrap(arr);  
                  
                int numBytes = sc.read(buf); // 讀取字符串  
                if(numBytes == -1)  
                {  
                    System.out.println("[Warning!] A client has been closed.");  
                    closeChannel();  
                    return;  
                }  
                String str = new String(arr); // 將讀取到的byte內容轉為字符串型態  
                if ((str != null) && !str.equals(" ")) {  
                    process(str); // 邏輯處理  
                    System.out.println(sc.socket().getRemoteSocketAddress().toString()  
                            + " > " + str);  
                    state = 1; // 改變狀態  
                    sk.interestOps(SelectionKey.OP_WRITE); // 通過key改變通道註冊的事件  
                    sk.selector().wakeup(); // 使一個阻塞住的selector操作立即返回  
                }  
            }  
          
            private void send() throws IOException  {  
                // get message from message queue  
                  
                String str = "Your message has sent to "  
                        + sc.socket().getLocalSocketAddress().toString() + "\r\n";  
                ByteBuffer buf = ByteBuffer.wrap(str.getBytes()); // wrap自動把buf的position設為0,所以不需要再flip()  
          
                while (buf.hasRemaining()) {  
                    sc.write(buf); // 回傳給client回應字符串,發送buf的position位置 到limit位置為止之間的內容  
                }  
                  
                state = 0; // 改變狀態  
                sk.interestOps(SelectionKey.OP_READ); // 通過key改變通道註冊的事件  
                sk.selector().wakeup(); // 使一個阻塞住的selector操作立即返回  
            }  
              
            void process(String str) {  
                // do process(decode, logically process, encode)..  
                // ..  
            }  
        }
     
    }

    通信服务端示例代码的关键:

    • Reactor反应器建立完serverSocket管道后,初始注册一个OP_ACCEPT事件(选择键)到,Selector选择器中;并为该事件(选择键)绑定一个连接建立AccptorHandler处理器;
    • Reactor的服务线程,会循环不断通过Selector选择器的select调用轮询就绪事件;当有就绪事件(选择键)时分发给相应的事件处理器;初始建立连接后会轮询到一个OP_ACCEPT就绪键,分发给AccetorHandler处理器;
    • AccetorHandler处理器的作用两个,一个是接受新连接SocketChannel;另一个改变选择键的类型为OP_READ,并创建一个输入输出的IOHandler处理器,作为附件绑定到OP_READ选择键上,AccetorHandler处理器和Reactor反应器使用同一个选择器;
    • IOHandler,负责数据输入、业务处理、结果输出;业务处理后,改变interestOps改变注册事件为OP_WTRIT,并唤醒阻塞事件(OP_READ);
    • Reactor反应器,selector选择器轮询获取到OP_WRITE事件后,会在分发时获取对应的IOHandler处理器;进行结果返回处理;

    优点:相对于传统的一连接一线程,是基于Java NIO实现,反应器模式不用再启动成千上万的线程了。

    缺点:当其中某个handler处理器阻塞时,也会导致其他所有handler无法执行;handler不仅仅负责输入、输出业务处理,还包括建             立连接监听的AcceptorHandler处理器,问题很严重;其次也不能充分利用多核心资源;

    多线程的Reactor反应器模式

    多线程池的Reactor反应器演进在两个方面:

    • 首先升级Handler处理器,既要使用多线程,又要高效率,则可以考虑使用线程池。
    • 其次升级Reactor反应器,考虑引入多个选择器,替身选择大量ServerSocketChannel通道的能力;

    总体设计思路如下:

    • 负责输入输出处理的IOHandler处理器的执行,放入独立的线程池中,这样业务处理线程和负责服务监听和IO事件查询的反应器线程相互隔离,避免服务器连接监听收到阻塞。
    • 如果服务器是多核的CPU,可以将反应器线程拆分为多个自反应器(SubReactor)线程;同时引入多个选择器,每个SubReactor子线程负责一个选择器。这样充分释放了系统资源的能力,也提高了反应器管理大量连接,提升选择大量通道的能力;

    多线程反应器模式

    实例代码参考https://www.cnblogs.com/crazymakercircle/p/9833847.html 5.3. 多线程Reactor的参考代码

    展开全文
  • 它的相关方程式有哪些呢。【定义】复分解反应是由两种化合物互相交换成分,生成另外两种化合物的反应。复分解反应是四大基本反应类型之一。复分解反应的实质是发生复分解反应的两种物质在水溶液中交换离子,结合成难...

    在之前的文章中,小编也提到了分解反应就是将一种物质分解为多种物质。那么,什么是复分解反应呢。它的相关方程式有哪些呢。

    【定义】

    复分解反应是由两种化合物互相交换成分,生成另外两种化合物的反应。复分解反应是四大基本反应类型之一。

    复分解反应的实质是发生复分解反应的两种物质在水溶液中交换离子,结合成难电离的物质——沉淀、气体或弱电解质。可简记为AB+CD→AD+CB。

    da95d8575ba0e8920279b830261a7320.png

    【相关方程式】

    1、碱性氧化物+酸→盐+H2O

    Fe2O3+6HCl===2FeCl3+3H2O

    CuO+H2SO4==CuSO4+H2O

    ZnO+2HNO3==Zn(NO3)3+H2O

    2、盐1+盐2→新盐1+新盐2

    KCl+AgNO3===AgCl↓+KNO3

    NaCl+AgNO3===AgCl↓+NaNO3

    Na2SO4+BaCl2===BaSO4↓+2NaCl

    BaCl2+2AgNO3===2AgCl↓+Ba(NO3)2

    3、盐+碱→新盐+新碱

    CuSO4+2NaOH===Cu(OH)2↓+Na2SO4蓝色沉淀

    FeCl3+3NaOH===Fe(OH)3↓+3NaCl红褐色沉淀溶解、溶液呈黄色

    Ca(OH)2+Na2CO3==CaCO3↓+2NaOH有白色沉淀生成工业制烧碱、实验室制少量烧碱

    NaOH+NH4Cl===NaCl+NH3↑+H2O生成使湿润石蕊试纸变蓝色的气体应用于检验溶液中的铵根离子

    4、碱+酸→盐+H2O

    Cu(OH)2+2HCl===CuCl2+2H2O

    Cu(OH)2+H2SO4===CuSO4+2H2O

    NaOH+HCl===NaCl+H2O

    2NaOH+H2SO4===Na2SO4+2H2O

    NaOH+HNO3===NaNO3+H2O

    Mg(OH)2+2HNO3===Mg(NO3)2+2H2O

    Ba(OH)2+H2SO4===BaSO4↓+2H2O

    Al(OH)3+3HCl=======AlCl3+3H2O白色固体溶解胃舒平治疗胃酸过多

    5、酸+盐→新盐+新酸

    CaCO3+2HCl===CaCl2+H2O+CO2↑实验室制取CO2、除水垢

    Na2CO3+2HCl===2NaCl+H2O+CO2↑有使澄清石灰水变浑浊的气体泡沫灭火器原理

    H2SO4+BaCl2===BaSO4↓+2HCl生成白色沉淀、不溶解于稀硝酸检验SO42-的原理

    Ba(NO3)2+H2SO4===BaSO4↓+2HNO3生成白色沉淀、不溶解于稀硝酸检验Ba2+的原理

    NaHCO3+HCl===NaCl+H2O+CO2↑有使澄清石灰水变浑浊的气体泡沫灭火器原理

    有时候复分解反应会和中和反应重合,生成相应的盐和水。大家要注意各类反应之间相互交叉的地方。同时,注意对于公式的背诵记忆。

    展开全文
  • 有哪些原理可循的呢? 工业电容触摸屏: 电容触摸屏 电容屏所谓的“漂移”,主要指以下几种情况: 1、对触控操作作出误动作,即触摸A点,却对B点作出触摸反应; 2、没有触摸却作出误动作,即身体或导电物等靠近屏幕,...

    工业液晶屏的触摸屏有分为非触摸、电阻触摸和电容触摸等多种触摸方式,而电容触摸是较为常见的触摸方式,当工业电容屏出现故障的时候该如何解决?有哪些原理可循的呢?
    工业电容触摸屏:

    电容触摸屏

    电容屏所谓的“漂移”,主要指以下几种情况:

    1、对触控操作作出误动作,即触摸A点,却对B点作出触摸反应;

    2、没有触摸却作出误动作,即身体或导电物等靠近屏幕,还没有触碰,就作出了触摸反应;

    3、对触控操作无动作,即已经用手指触碰到触摸屏,但屏幕却没有做出触摸反应。

    在介绍导致“漂移”的原因之前,有必要先介绍一下电容屏的工作原理。

    电容屏是利用人体的电流感应进行工作的。电容式触摸屏是一块四层复合玻璃屏,玻璃屏的内表面和夹层各涂有一层ITO(透明导电膜),最外层是一薄层矽土玻璃保护层,夹层ITO涂层作为工作面,四个角上引出四个电极,内层ITO为屏蔽层以保证良好的工作环境。

    当手指触摸在金属层上时,由于人体电场,用户和触摸屏表面形成以一个耦合电容,对于高频电流来说,电容是直接导体,于是手指从接触点吸走一个很小的电流。这个电流分从触摸屏的四角上的电极中流出,并且流经这四个电极的电流与手指到四角的距离成正比,控制器通过对这四个电流比例的精确计算,得出触摸点的位置。

    文章原创来于工业液晶屏:https://www.leehon.com,转载请注明出处

    正是由于电容屏的这种工作原理,才导致了跳屏现象的存在。在弄清了电容屏的工作原理以后,就很容易知道导致电容屏“漂移”的原因了。

    关于关于电容屏出现“漂移”现象的原因大概就是如此,不论是什么设备,出现故障时首先要找出原因所在才能对症下药。

    展开全文
  • 不少人都“谈荧光剂色变”的“应激反应”,的确,荧光剂对皮肤的损害很大,但“检测出荧光反应”就等于“添加了荧光剂”吗?本文将带你了解荧光剂的前世今生,告诉你荧光增白剂到底是什么,在哪里应用,什么危害...

    不少人都有“谈荧光剂色变”的“应激反应”,的确,荧光剂对皮肤的损害很大,但“检测出荧光反应”就等于“添加了荧光剂”吗

    本文将带你了解荧光剂的前世今生,告诉你荧光增白剂到底是什么,在哪里应用,有什么危害,以及与荧光反应的关系。

    01

    什么是荧光增白剂?

    荧光增白剂又称荧光剂或荧光漂白剂,它是一种荧光染料(白色染料),主要被应用于纺织、造纸、塑料及洗涤等行业。

    荧光增白剂产生作用的原理:在紫外光的照射下,荧光增白剂会吸收掉UV而发出蓝色荧光(约410-480nm波长),在明亮的环境中,这样的一种荧光就从视觉上对冲了黄色反光,从而使物体表面看起来变得更白,是一种光学上的补色、增亮

    43be94e8ed051e1f2ea31d429e6c1b4c.png

    02

    荧光增白剂有什么用?

    很久以前人们制作白色物品主要是靠传统的漂白、上蓝工艺获得,但给人却有一种陈旧的感觉。使用荧光增白剂,其增白效果是上蓝加白和化学漂白所无法相比的,之后荧光增白剂的应用范围越来越广泛,由开始的纺织品行业逐步发展到食品、食品接触材料、化妆品、纸制品、洗涤用品等多种行业。

    在食品行业中,荧光增白剂除了具有明显的增白作用外,还有一定的保鲜、防腐作用,目前荧光增白剂是不允许添加在食品中的。荧光增白剂在食品接触材料中的使用可以提高产品的白度和艳度,从而降低包装成本。

    在洗涤和纺织用品行业中,荧光增白剂使被洗涤的白色纺织品视觉效果上恢复到洁白、明亮的状态,不仅改善了外观,提高了品质和档次,同时提升了其商业价值。荧光增白剂越来越凸显它的重要性。

    f20c90d0a78cf33df6896e624f59ebed.png

    在日化行业,我国法规并未明确禁止荧光增白剂在日用品和化妆品中的使用适量添加荧光增白剂是符合法规的细心的消费者会发现一些国际大牌的产品成分中会有荧光增白剂“联苯乙烯二苯基二磺酸二钠”的身影。

    然而,也有一些不良厂家为了立即美白效果会在面膜产品中过量添加荧光增白剂,给消费者带来潜在的安全风险。

    03

    有荧光的物质都叫荧光增白剂?

    常常被问到在VISIA检测中或在荧光检测笔照射下发现有荧光,怀疑产品有添加荧光增白剂,要找商家索赔。

    acaab64e01dcdfcc79fec6be806a0c93.png

    告诉你,其实大可不必紧张!

    如何区分荧光反应和荧光增白剂

    荧光剂可以产生荧光反应,但是能产生荧光反应的物质不只有荧光剂

    荧光的产生是由处于基态的化合物分子在吸收紫外或可见光的能量后,电子跃迁至高能量轨道激发态。处于激发态的分子通过振动弛豫或内部转换过程跃迁到分子的最低激发态的最低振动能级,再发生辐射跃迁回到基态,发射光子产生荧光。

    产生荧光的必要条件是其结构中有荧光基团,荧光基团都是含有不饱和键的基团,当这些基团是分子的共轭体系的一部分时,则该化合物可能产生荧光。常见的荧光基团有

    d0fb34721907badf130a02f50eafd38a.png

    分子结构中含有一个或多个取代基时(如-OH、-NH2、-COOH)可以增强或减弱荧光。

    洗涤和日化产品常用的荧光增白剂联苯乙烯二苯基二磺酸二钠的结构式如下:

    9fe3db64f2338226174464034d6b4716.png

    天然维生素E,有荧光反应,但不是荧光剂,其分子结构式如下:

    c6184acfbc68f26fd54a841804973789.png

    所以,有荧光反应的不一定都是荧光增白剂!!

    化妆品中哪些成分会产生荧光反应

    由荧光反应的基团可知,能产生荧光的物质多种多样。具有荧光反应的物质普遍存在于自然界中,如虾、蟹、水母、萤火虫等动物体内;人体也含有荧光物质,主要是氨基酸、维生素、蛋白质、荷尔蒙等;酱油、普洱茶、白酒、红茶、咖啡等发酵食品也可以产生荧光反应。

    化妆品中常见的成分水杨酸、维生素A、维生素E、黄酮类、多酚类、白藜芦醇、鞣花酸,植物提取物如叶绿素、银杏黄酮、苦参生物碱等都可以在紫外线的激发作用下出现荧光反应。

    活性成分黄酮类母体结构:

    2c6b8df84608ca0b30746ecddc8ca6bd.png

    天然抗氧化剂白藜芦醇结构:

    f2002487ca2b47c10ef9f42f9b623c05.png

    04

    荧光增白剂护肤品有哪些危害?

    虽然国家并未禁止在护肤品中添加荧光增白剂,化妆品生产企业在选用原料时,应当符合国家有关法规、标准、规范的相关要求,并对原料进行安全性风险评估,承担产品质量安全责任。

    所以,荧光增白剂添加于化妆品中并不是绝对安全的。有的不良厂商为了即时效果,会在产品中大量添加荧光增白剂来达到即时美白的功效,皮肤越是暗哑、发黄,效果越好。但是长期使用这类产品会给我们带来什么危害呢?

    f2934eac9cbd43853c4afd480ee2c052.png

    荧光增白剂对人体皮肤的安全性研究主要有以下几个方面:

    01

    皮肤上的吸附及经皮吸收

    Luckhaus以裸鼠进行相关实验:结果显示裸鼠的表皮层附着有荧光增白剂,荧光增白剂可能与皮肤的角质层以某种化学键相结合,残留于皮肤上,从而不同程度的影响皮肤健康

    02

    皮肤刺激性

    Keplinger和Fancher等以5~10g/kg的荧光增白剂溶液对小鼠进行皮肤封包试验,结果表明,局部皮肤出现轻微红斑反应

    03

    皮肤致敏性

    上海市劳动卫生职业病防治研究所报道了65例荧光增白剂致成衣工职业性皮肤病的病例。报道中指出这些工人均有荧光增白剂接触史,患病人数占受检总人数的73.9%,说明荧光增白剂有较强的致敏性

    04

    面部皮炎概率增加

    广东省皮肤病医院发现7例经Visia皮肤检测系统检测发现面部含荧光增白剂的病例,其中3例为“爆发性痤疮”的患者,4例为“黄褐斑”突然加重的患者,这些患者均长期使用了含荧光增白剂的面膜。

    00d7177ef89d0f5573a6d035f7fb2a51.png

    05

    做检测发现有荧光反应怎么办?

    首先我们分析一下,可能有两种原因:

    一是所用产品添加了荧光增白剂,此类产品长期接触会增加过敏性皮炎的几率;

    二是产品含有能产生荧光反应的成分比如维生素、黄酮类、多酚类,这些并不是荧光增白剂,不会对皮肤造成危害。

    其次,如果确实产品成分中有发现添加了荧光增白剂,如果是正规厂商的产品也不必恐慌,安全风险在可控范围之内。若非正规厂家,建议果断放弃,不要继续使用,重新购买正规厂商产品,或者产品成分中不含荧光增白剂的产品。

    总之一句话,不能“谈荧色变”,理性看待荧光反应

    参考文献

    1. 张建成. 现代光化学[M].化学工业出版社,2016

    2. 姜楠等.荧光增白剂应用现状及研究进展[J].中国卫生工程学,2019(3):476-480

    3. Luckhaus G, Löser E. Study by fluorescence microscopy of the effect of fluorescent whitening agents on the skin of mice[J].Environ Qual saf Suppl,1975(4):198-202.

    4.Keplinger ML, Fancherr OE. Toxicologic studies of four fluorescent whitening agents[J]. Oxicol Applied Pharmacol,1974(27):494-506.

    5. 夏宝凤,汪森榕,唐春元.荧光增白剂所致成衣工职业性皮肤疾患65例报告[J].中国工业医学杂志, 1994,3: 182-183.

    6.  艾菁等.荧光增白剂对人体皮肤的安全性分析[J].中国美容医学,2016,3:104-107

    7.  董仲生.荧光增白剂的应用及其使用安全性[J].中国洗涤用品工业,2011(4):31-39

    展开全文
  • 手机触摸屏以电容式触摸屏为主,通过感应人体的电流来发生触控反应。它的原理在于:人本身就带电,因此当手指与手机触摸屏进行接触时,就会对手机触摸屏下面的电荷产生影响,屏幕控制器发现电荷变化后,把坐标反馈给...
  • 高频开关电源工作原理及特点有哪些?开瑞小编为你介绍:开关K以必定的时刻间隔重复地接通和断开,在开关K接通时,输进电源E经过开关K和滤波电路供给给负载RL,在全部开关接通期间,电源E向负载供给能量;当开关K断开...
  • DNS劫持又称域名劫持,是指在劫持的网络范围内拦截域名解析的请求,分析请求的域名,把审查范围以外的请求放行,否则返回假的IP地址或者什么都不做使请求失去响应,其效果就是对特定的网络不能反应或访问的是假网址...
  • webpack原理与实战

    2021-01-02 03:09:41
    以做出对应的反应。 3. 从配置的<code>entry入口文件开始解析文件构建AST语法树,找出每个文件所依赖的文件,递归下去。 4. 在解析文件递归的过程中根据文件类型和loader配置找出合适的loader用来对文件...
  • 在DOM操作中,事件对我们而言,是一个神奇的东西,它的内在实现原理,是什么样的?...描述一个事件的重点有哪些?搞清楚什么事件,那么必须搞明白,在JavaScript的层面上,什么是JavaScript应该关注的重点
  • 7. 精细化学品分析中使用的化学分析和仪器分析方法有哪些?各自有什么特点? 答:精细化学品分析中使用的化学分析方法有重量分析,滴定分析(酸碱.配位.氧化还原.沉淀滴定法)特点是:通常用于高含量或中含量组分的测定...
  • 如果你告诉20世纪80年代的人们可以在互联网上购物,他们会什么样的反应?•谁会愿意在网上买衣服?别说梦话了。•网上买衣服试都没法试,靠一张图片就要我付钱?•一定是骗子,想骗钱想疯了吧。如果你向他们...
  • Reactive 架构才是未来

    千次阅读 2020-05-21 13:33:52
    Reactive 编程模型有哪些价值?它的原理是什么?如何正确使用?本文作者将根据他学习和使用的经历,分享 Reactive 的概念、规范、价值和原理。欢迎同学们共同探讨、斧正。 Reactive 和 Reactive programming ...
  • 1. 导致系统不可用的原因有哪些?保障系统稳定高可用的方案有哪些?请分别列举并简述。 引起故障的原因 硬件故障 软件 bug 系统发布 并发压力 网络攻击 外部灾害 解决方案如下: 解耦 高内聚、低耦合的组件设计...
  • 这周开始我会讲关于NiO的一切,底层原理是什么,应用架构有哪些,如何利用其优势构建高性能服务器,欢迎关注。 在介绍NIO之前有必要了解下TCP协议,因为目前多数应用都是给予应用层进行操作,导致隐藏了大量的网路...
  • 根据药水性质分为酸性时刻额和碱性蚀刻,蚀刻的原理其实很简单,通俗点说就是通过化学药水和铜反应,将芯板上露出来的铜腐蚀掉,没有接触过蚀刻的朋友可能疑问:药水怎么知道哪些铜(也就是线路图形部分)是要保留...
  • IT技术之家 2018-06-27 21:45:00很开心,上半年发布的spring boot 2中,默认的web 容器...这周开始我会讲关于NiO的一切,底层原理是什么,应用架构有哪些,如何利用其优势构建高性能服务器,欢迎关注。在介绍NIO之...
  • 大量的TIL存在,就表示机体对抗肿瘤的免疫反应正在发生。基于免疫原理的其中一类抗癌疗法,便是通过发动TIL,来让它们杀死癌细胞。而肿瘤科医师,需要观察病理切片,识别肿瘤组织的免疫特征,从而判断免疫疗法对哪些...
  • 【简答题】催化裂化分馏塔、 延迟焦化分馏塔与 常压精馏塔有哪些异同点?【简答题】为什么加氢工艺要采用大量氢气循环?循环氢的作用是什么?用什么指标表示氢气的循环量?【简答题】为什么说 再生器的烧焦能力 决定 ...
  • 传统上,激光雷达可用于工业的安全检测领域,就像科幻片中的激光墙,当人进入时,系统可以快速反应,发出预警。  同时,激光雷达在空间测绘领域也广泛应用。简单来说,其工作原理是通过发射激光来扫描被...
  • 3D打印技术最全解析:从设计到工艺

    千次阅读 2018-06-08 15:07:08
    SLA作为3D打印成型方式的一种,因其材料多样化,价格便宜,已被大众所接受,在众多领域得到广泛的应用,今天,小编就带大家一起了解一下什么是SLA工艺及SLA工艺对产品设计的要求及工艺原则有哪些?1.工艺概述SLA全称...
  • 布林带的交易技巧

    2020-07-02 09:43:56
    那么在外汇交易中布林带做单的方法有哪些呢? 1、布林指标的上轨和下轨之间的关系反应市场价格的运行状态,收口表示市场价格可能选择方向或者脱离此前的趋势状态;开口表示脱离此前趋势状态后价格进一步的空间拓展...
  • .NET 初中级面试题

    2020-08-02 15:29:38
    你用过哪些?说一下工厂模式; 说一下什么是面向对象? 说一下抽象类和接口的区别? 说一下MVC路由原理? .net 请求管道?(记不太清了,大概意思就是在请求处理前后,对请求做处理) 页面反应很慢怎么排查?怎么...
  • 软件测试经典面试题 (超实用)

    热门讨论 2012-02-16 13:48:08
    3、测试的策略有哪些? 5 4、正交表测试用例设计方法的特点是什么? 5 5、描述使用bugzilla缺陷管理工具对软件缺陷(BUG)跟踪的管理的流程? 5 6、你觉得bugzilla在使用的过程中,有什么问题? 5 7、描述测试用例...
  • 对于非计算机专业而言,程序设计的学习助于理解计算机的能力所在,理解哪些是计算机擅长解决的问题,怎样的方式方法是计算机擅长的手段,从而能更好地利用计算机来解决本专业领域内的问题。 C语言是古老而长青的...
  • 神经网络提取特征的方式有哪些 介绍下你了解的轻量级CNN模型 网络模型压缩方面的剪枝,量化和二值化编码 基于视频的C3D三维网络模型有听说过嘛 2.5D卷积呢 什么是空洞卷积,什么是反卷积,作用是什么 如何...

空空如也

空空如也

1 2 3
收藏数 46
精华内容 18
关键字:

反应原理有哪些