国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Nginx+netty實現(xiàn)tcp負載均衡,獲取客戶端真實ip

這篇具有很好參考價值的文章主要介紹了Nginx+netty實現(xiàn)tcp負載均衡,獲取客戶端真實ip。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

nginx配置

在nginx.conf文件中,events,http同級添加配置

stream {

   upstream tcp {
       server 127.0.0.1:8888 weight=1;
       server 127.0.0.1:8889 weight=1;
  }
  server {
    listen 8880;
    proxy_pass tcp;
	proxy_protocol on;        #僅此一句重點,用以判斷獲取客戶端真實ip
  }
}

啟動nginx服務(wù)

netty代碼

package com.alexyang.nettyandthread.netty2;

/**
 * @author yqc
 * @version 1.0
 * @description netty+nginx
 * @date 2023-06-30 9:22
 */

import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

@Component
public class ServerNetty implements ApplicationRunner {
    final static Logger log = LogManager.getLogger(ServerNetty.class);

    private int port = 8888;
    private String ip = "127.0.0.1";

    public void start() throws InterruptedException {
        NioEventLoopGroup boss = null;
        NioEventLoopGroup worker = null;
        try {
            ServerBootstrap b = new ServerBootstrap();
            boss = new NioEventLoopGroup();
            worker = new NioEventLoopGroup();
            b.group(boss, worker);
            b.channel(NioServerSocketChannel.class);
            b.localAddress(port);
            b.option(ChannelOption.SO_KEEPALIVE, true);//是否開啟TCP心跳機制
            b.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
            b.childHandler(new ChannelInitializer() {
                @Override
                protected void initChannel(Channel channel) throws Exception {
                    channel.pipeline().addLast("decoder",new DecodeProxy()); // 增加這個自定義的解碼器
                    channel.pipeline().addLast(new ServerHandler());
                }
            });
            log.info("啟動 netty 服務(wù)端");
            ChannelFuture future = b.bind(ip, port).sync();
            log.info("服務(wù)器啟動成功,監(jiān)聽端口{}", future.channel().localAddress());
            future.channel().closeFuture().sync();
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            //關(guān)閉線程組,釋放資源
            worker.shutdownGracefully();
            boss.shutdownGracefully();
        }

    }

    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("執(zhí)行.............");
        start();
    }
}

package com.alexyang.nettyandthread.netty2;

/**
 * @author yqc
 * @version 1.0
 * @description nginx代理netty tcp服務(wù)端負載均衡,nginx stream要打開 proxy_protocol on; 配置
 * @date 2023-06-30 10:09
 */

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.util.Attribute;
import io.netty.util.AttributeKey;

import java.nio.charset.Charset;
import java.util.List;

/**
 * @Description nginx代理netty tcp服務(wù)端負載均衡,nginx stream要打開 proxy_protocol on; 配置
 */
public class DecodeProxy extends ByteToMessageDecoder {

    /**
     * 保存客戶端IP
     */
    public static AttributeKey<String> key = AttributeKey.valueOf("IP");

    /**
     * decode() 會根據(jù)接收的數(shù)據(jù),被調(diào)用多次,直到確定沒有新的元素添加到list,
     * 或者是 ByteBuf 沒有更多的可讀字節(jié)為止。
     * 如果 list 不為空,就會將 list 的內(nèi)容傳遞給下一個 handler
     *
     * @param ctx     上下文對象
     * @param byteBuf 入站后的 ByteBuf
     * @param out     將解碼后的數(shù)據(jù)傳遞給下一個 handler
     * @throws Exception
     */
    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf, List<Object> out) throws Exception {

        /*消息打印--------------------------*/
        byte[] bytes = printSz(byteBuf);
        String message = new String(bytes, Charset.forName("UTF-8"));
        //logger.info("從客戶端收到的字符串:" + message);
        /*消息打印--------------------------*/

        if (bytes.length > 0) {

            //判斷是否有代理
            if (message.indexOf("PROXY") != -1) {
                //PROXY MSG: PROXY TCP4 192.168.12.52 192.168.12.52 1096 5680\r\n
                System.out.println("PROXY MSG: " + message.substring(0, message.length() - 2));
                if (message.indexOf("\n") != -1) {
                    String[] str = message.split("\n")[0].split(" ");
                    System.out.println("Real Client IP: " + str[2]);
                    Attribute<String> channelAttr = ctx.channel().attr(key);
                    //基于channel的屬性
                    if (null == channelAttr.get()) {
                        channelAttr.set(str[2]);
                    }
                }

                //清空數(shù)據(jù),重要不能省略
                byteBuf.clear();
            }

            if (byteBuf.readableBytes() > 0) {
                //logger.info("out add!!!");
                out.add(byteBuf.readBytes(byteBuf.readableBytes()));
            }
        }
    }


    /**
     * 打印byte數(shù)組
     *
     * @param newBuf
     */
    public byte[] printSz(ByteBuf newBuf) {
        ByteBuf copy = newBuf.copy();
        byte[] bytes = new byte[copy.readableBytes()];
        copy.readBytes(bytes);
        //logger.info("字節(jié)數(shù)組打印:" + Arrays.toString(bytes));
        return bytes;
    }
}

package com.alexyang.nettyandthread.netty2;


/**
 * @description ServerHandler
 * @author yqc
 * @date 2023-06-30 9:23
 * @version 1.0
 */

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.Attribute;

import java.nio.charset.Charset;

public class ServerHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
        ctx.fireChannelRegistered();
    }

    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
        ctx.fireChannelUnregistered();
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("收到鏈接:" + ctx.channel().remoteAddress());
        ctx.fireChannelActive();
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        ctx.fireChannelInactive();
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        Attribute<String> channelAttr = ctx.channel().attr(DecodeProxy.key);
        //基于channel的屬性
        if(null != channelAttr.get()){
         System.out.println("IP地址--------------- :" + channelAttr.get());
        }
        ByteBuf in = (ByteBuf) msg;
        System.out.println("收到客戶端" + ctx.channel().remoteAddress().toString() + "內(nèi)容:" + in.toString(Charset.forName("UTF-8")));
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        ctx.fireChannelReadComplete();
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        ctx.fireUserEventTriggered(evt);
    }

    @Override
    public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception {
        ctx.fireChannelWritabilityChanged();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.fireExceptionCaught(cause);
    }
}

啟動2個服務(wù)netty服務(wù)設(shè)置nginx中8888,8889端口。
使用tcp工具連接并發(fā)送數(shù)據(jù)測試

參考博客
參考鏈接1
參考鏈接2文章來源地址http://www.zghlxwxcb.cn/news/detail-736409.html

到了這里,關(guān)于Nginx+netty實現(xiàn)tcp負載均衡,獲取客戶端真實ip的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 原來還可以客戶端負載均衡

    原來還可以客戶端負載均衡

    歡迎來到我的博客,代碼的世界里,每一行都是一個故事 在數(shù)字化的舞臺上,服務(wù)如同優(yōu)雅的舞者,但如何讓它們保持優(yōu)雅的舞姿面對巨大的觀眾呢?這就需要一位懂得平衡的舞者——客戶端負載均衡。就像是一場數(shù)字化的舞蹈,本文將帶你進入這個神秘的世界,揭示客戶端

    2024年02月21日
    瀏覽(16)
  • 客戶端負載均衡工具Ribbon

    客戶端負載均衡工具Ribbon

    Ribbon介紹 目前主流的負載方案分為以下兩種: 集中式負載均衡,在消費者和服務(wù)提供方中間使用獨立的代理方式進行負載,有硬件的(比如 F5),也有軟件的(比如 Nginx)。 客戶端根據(jù)自己的請求情況做負載均衡,Ribbon 就屬于客戶端自己做負載均衡。 Spring Cloud Ribbon是基于

    2024年02月09日
    瀏覽(21)
  • 客戶端負載均衡策略:loadBalancer,ribbon

    客戶端負載均衡是指在分布式系統(tǒng)中,客戶端通過某種策略將請求分發(fā)到多個服務(wù)提供者實例上,以達到負載均衡和提高系統(tǒng)的可用性和性能。 在 Java 生態(tài)系統(tǒng)中,Ribbon 是一個常用的客戶端負載均衡框架,它是 Netflix 開源的一部分,被廣泛應(yīng)用于 Spring Cloud 中。Ribbon 提供了

    2024年02月08日
    瀏覽(26)
  • 基于grpc-java開發(fā)的普通工程在k8s內(nèi)部署多實例,如何實現(xiàn)客戶端流量的負載均衡

    基于grpc-java開發(fā)的普通工程在k8s內(nèi)部署多實例,如何實現(xiàn)客戶端流量的負載均衡

    本文主要討論通過grpc-java開發(fā)的普通的java grpc工程,以多實例的方式部署在容器編排平臺kubernetes(以下簡稱k8s)上,如何能夠?qū)崿F(xiàn)讓同樣部署在k8s 集群內(nèi)的客戶端請求流量均衡的分發(fā)到多個grpc應(yīng)用部署實例上去。 grpc服務(wù)端程序在k8s內(nèi)部署的多個實例通過headless service暴露服

    2024年01月17日
    瀏覽(18)
  • 使用Go語言的HTTP客戶端進行負載均衡

    使用Go語言的HTTP客戶端進行負載均衡

    負載均衡是分布式系統(tǒng)中的重要概念,它用于將流量分散到多個服務(wù)器或服務(wù)上,以實現(xiàn)更好的性能、可靠性和可擴展性。在Go語言中,可以使用HTTP客戶端進行負載均衡,確保請求被均勻地分配到多個服務(wù)器或服務(wù)上。 下面是一個使用Go語言HTTP客戶端進行負載均衡的示例:

    2024年01月21日
    瀏覽(27)
  • netty-發(fā)起tcp長連接(包含客戶端和服務(wù)端)

    Netty是一個高性能、異步事件驅(qū)動的NIO框架,它提供了對TCP、UDP和文件傳輸?shù)闹С帧?Netty是對JDK自帶的NIO的API進行封裝,具有高并發(fā),高性能等優(yōu)點。 項目中經(jīng)常用到netty實現(xiàn)服務(wù)器與設(shè)備的通信,先寫服務(wù)端代碼: 服務(wù)端處理類代碼: 接下來 模擬 客戶端: 客戶端處理類代

    2024年02月12日
    瀏覽(18)
  • 使用Netty構(gòu)建TCP和UDP服務(wù)器和客戶端

    Netty是一個基于Java NIO實現(xiàn)的網(wǎng)絡(luò)通信框架,提供了高性能、低延遲的網(wǎng)絡(luò)通信能力。使用Netty構(gòu)建TCP和UDP服務(wù)器和客戶端非常簡單,下面是一個簡單的示例代碼: 構(gòu)建TCP服務(wù)器 構(gòu)建TCP客戶端 構(gòu)建UDP服務(wù)器 構(gòu)建UDP客戶端 ? 上述示例代碼中,分別定義了一個TCP服務(wù)器、TCP客戶

    2024年02月16日
    瀏覽(23)
  • SpringBoot搭建Netty+Socket+Tcp服務(wù)端和客戶端

    yml配置:? ? 完成,啟動項目即可自動監(jiān)聽對應(yīng)端口 這里為了測試,寫了Main方法,可以參考服務(wù)端,配置啟動類 ,實現(xiàn)跟隨項目啟動 ? ......想寫就參考服務(wù)端...... 有測試的,,,但是忘記截圖了................

    2024年02月15日
    瀏覽(25)
  • Spring Cloud(Finchley版本)系列教程(二) 客戶端負載均衡Ribbon

    Spring Cloud(Finchley版本)系列教程(二) 客戶端負載均衡Ribbon

    Spring Cloud(Finchley版本)系列教程(二) 客戶端負載均衡Ribbon 目前主流的負載均衡方案有兩種,一種是集中式均衡負載,在消費者與服務(wù)提供者之間使用獨立的代理方式進行負載,比如F5、Nginx等。另一種則是客戶端自己做負載均衡,根據(jù)自己的請求做負載,Ribbon就屬于客戶端自己

    2024年02月09日
    瀏覽(47)
  • 【kafka】Java客戶端代碼demo:自動異步提交、手動同步提交及提交顆粒度、動態(tài)負載均衡

    【kafka】Java客戶端代碼demo:自動異步提交、手動同步提交及提交顆粒度、動態(tài)負載均衡

    kafka版本為3.6,部署在3臺linux上。 maven依賴如下: 生產(chǎn)者、消費者和topic代碼如下: 這里先簡單解釋一下, kafka的topic只是一個邏輯上的概念,實際上的物理存儲是依賴分布在broker中的分區(qū)partition來完成的 。kafka依賴的zk中有一個 __consumer_offsets [1]話題,存儲了所有consumer和g

    2024年01月19日
    瀏覽(27)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包