shadowsocks-rust icon indicating copy to clipboard operation
shadowsocks-rust copied to clipboard

The server chosen by balancer is NOT the "best"

Open robot-dot-win opened this issue 3 months ago • 10 comments

I have a local transparent proxy with the balancer:

{
    "locals": [
        {
            "local_address": "127.0.0.1",
            "local_port": 61082,
            "protocol": "redir",
            "tcp_redir": "redirect"
        }
    ],

    "servers": [
        // The domestic server(local host):
        {
            "address": "127.0.0.1",
            "port": 51080,
            "method": "none",
            "tcp_weight": 1.0
        }

        // The overseas server:
        {
            "address": "65.x.x.x",
            "port": xxxx,
            "method": "aes-256-gcm",
            "password": "password_string",
            "tcp_weight": 0.6
        },
    ],

    "balancer": {
        "max_server_rtt": 3,
        "check_interval": 120,
        "check_best_interval": 5
    },

    "mode": "tcp_only",
    "no_delay": false,
    "fast_open": true
}

I hope most traffic will be via the domestic server, and the overseas server will act as a backup. At the beginning the chosen server is domestic, but after a while the overseas server will be chosen and from then on it seems that the balancer will always think the overseas server as the best. See log please:

Image What did it happen and how to config? Thanks.

robot-dot-win avatar Oct 15 '25 00:10 robot-dot-win

Your "domestic server" has higher latency and not stable (standard deviation is larger), which is why balancer choose another server that has lower latency and more stable.

You could lower the weight from 0.6 to 0.01, which may help.

zonyitoo avatar Oct 15 '25 02:10 zonyitoo

You could lower the weight from 0.6 to 0.01, which may help.

Thanks, setting weight to 0.01 really works as expected.

But I still wonder how it judges which is the best. In fact under most conditions the local host(domestic) will performance much better than the overseas, 'coz most destinations are domestic.

robot-dot-win avatar Oct 15 '25 07:10 robot-dot-win

Shameless plug: In shadowsocks-go, I implemented the following client selection policies:

  • "round-robin": Selects clients sequentially, cycling through the list.
  • "random": Selects clients randomly.
  • "availability": Selects the client with the highest availability.
  • "latency": Selects the client with the lowest average latency.
  • "min-max-latency": Selects the client with the lowest maximum latency.

Sounds like "availability" is what you actually want. You can also customize the destination address to probe.

https://github.com/database64128/shadowsocks-go/blob/931b4033013a2df05471d11becf2e97ce4dce57f/docs/config.json#L542-L572

database64128 avatar Oct 15 '25 08:10 database64128

You could lower the weight from 0.6 to 0.01, which may help.

Thanks, setting weight to 0.01 really works as expected.

But I still wonder how it judges which is the best. In fact under most conditions the local host(domestic) will performance much better than the overseas, 'coz most destinations are domestic.

As you can see in your log, your local server's latency is higher.

zonyitoo avatar Oct 16 '25 09:10 zonyitoo

As you can see in your log, your local server's latency is higher.

Yes, that's what i'm wondering: how does it judge the latency? The RTT of ICMP Echo Reply from the overseas server is much much bigger than from the domestic server.

robot-dot-win avatar Oct 17 '25 01:10 robot-dot-win

https://github.com/shadowsocks/shadowsocks-rust/blob/37e801208db86c0e0e0d7209575fa8b23b0897b7/crates/shadowsocks-service/src/local/loadbalancing/ping_balancer.rs#L888-L925

It makes a HTTP request through shadowsocks' channel to http://detectportal.firefox.com/success.txt and checks the whole process time.

zonyitoo avatar Oct 17 '25 05:10 zonyitoo

It makes a HTTP request through shadowsocks' channel to http://detectportal.firefox.com/success.txt and checks the whole process time.

This doesn't seem reasonable, 'coz what users consider most is the ssservers' accessibility instead of the firefox site's accessibility! You do not need to care about the destinations' accessibility - that's what the guys who set up all the ssservers should care about.

robot-dot-win avatar Oct 17 '25 06:10 robot-dot-win

  • "round-robin": Selects clients sequentially, cycling through the list.
  • "random": Selects clients randomly.
  • "availability": Selects the client with the highest availability.
  • "latency": Selects the client with the lowest average latency.
  • "min-max-latency": Selects the client with the lowest maximum latency.

Sounds like "availability" is what you actually want. You can also customize the destination address to probe.

Strongly recommend the banlancer to support these policies!

robot-dot-win avatar Oct 17 '25 06:10 robot-dot-win

It makes a HTTP request through shadowsocks' channel to http://detectportal.firefox.com/success.txt and checks the whole process time.

This doesn't seem reasonable, 'coz what users consider most is the ssservers' accessibility instead of the firefox site's accessibility! You do not need to care about the destinations' accessibility - that's what the guys who set up all the ssservers should care about.

Balancer needs a common endpoint to estimate all servers' latency. Firefox's success.txt is a good choice, which is accessible from any countries by CDN.

shadowsocks' protocol doesn't have a ping command, so there is no way to know the exact latency of the tunnel itself.

I would accept PRs if anyone could help to implement all these policies in balancer.

zonyitoo avatar Oct 17 '25 08:10 zonyitoo

Balancer needs a common endpoint to estimate all servers' latency. Firefox's success.txt is a good choice, which is accessible from any countries by CDN.

Understood. But a user-defined endpoit for each ssserver seems much better, even though.

I would accept PRs if anyone could help to implement all these policies in balancer.

Thank you so much for your comment, and appreciate this feature very much.

robot-dot-win avatar Oct 17 '25 09:10 robot-dot-win