-
Notifications
You must be signed in to change notification settings - Fork 704
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use system's maximum concurrent TCP connections for net::Defaults.maxTCPConnections #10375
base: master
Are you sure you want to change the base?
Conversation
68933f6
to
92d8955
Compare
92d8955
to
7597fb3
Compare
I feel readDecimal and dataToDecimal are a bit ornate if we compare to say getTotalSystemMemoryKb or getFromCGroup which just open their /proc file, read a line from it and atoll on that |
looked at them ofc and thought about adding this func .. esp due to late reviews :) |
7597fb3
to
342435e
Compare
added a tiny fix on calling readDecimal (EOS included), refined its API doc .. kicking CI again (ole cypress failure) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some good things here that can go in - but a number that need feedback. I -really- don't want review getting lost and ignored in monster review threads of giant collections of commits. It is good to split them up - lets also push them in small batches to different PRs.
checkRemoval -> fine.
Simplify UnitTimeoutBase -> no idea - a huge change with no clear rationale.
Add 'UT' -> the 'UT' is not needed - lets not make up lots of new acronyms in commit messages it is implicit in UnitTestFoo - otherwise good to see a new test -> fine.
is "Remove WebSocketHandler's WS Ping timeout functionality" a nearly straight revert - if so good; lets include the word 'Revert' in the commit message - otherwise fine.
Like the Remove redundant 'Socket::isClosed()' - but I would prefer us to remove 'isOpen' to minimize the end-to-end diff across the code. We don't want non-functional renames of methods isClosed -> isOpen is not a win.
"Add safe ..." don't like creating big, redundant helpers like this. We already have similar code, using other helpers that does this - git grep for & re-use the same code there.
why tcp_max_orphans ?
Thanks!
a3b53eb
to
dd4b6ae
Compare
Not huge IMHO, but simplifying the unit test more to its point, which pattern is also more reusable for other users.
Fun fact, I read this abbreviation somewhere else .. and picked it up. OK.
I counted usage of both, and isOpen was used more often without inversion
(other items were either accepted or discussed in upcoming PRs) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When feedback is incorporated systematically please poke me to review again. Thanks.
88b0d10
to
2764bcd
Compare
Done. Remark: The requested removal of Socket::isOpen() instead of Socket::isClose() increased the diff as laid out earlier. Regardless, I hope it fits requirements as I also changed the field name to have the accessor match 1:1 w/o inverted logic. Other changes applied as requested as well. |
2764bcd
to
e97b802
Compare
e97b802
to
d95881e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lets get the first two commits in- but not the third - which needs re-working.
}; | ||
// - 4 tcp_max_orphans sockets per MB | ||
// - {4096M -> 16384}, {16384M -> 65536}, {65407M -> 262144}, ... | ||
const ssize_t tcp_max_orphans = readDecimal("/proc/sys/net/ipv4/tcp_max_orphans", 0); // ignored if n/a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really not sure that these are the right settings; or that we can interrogate the kernel to find a number here. Possibly nf_conntrack_max is something reasonable to check - but ... looking - it seems the kernel is not helpful in giving us a number here; so presuambly we have to get it from the configuration - and then perhaps just crop that to nf_conntrack_max and/or some algorithm based on file-max.
Please re-think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tcp_max_orphans is that memory bound freely available socket count, not getting reset.
This limit exists only to prevent simple denial-of-service attacks. Lowering this limit is not recommended. Network conditions might require you to increase the number of orphans allowed, but note that each orphan can eat up to ~64 kB of unswappable memory. The default initial value is set equal to the kernel parameter NR_FILE. This initial default is adjusted depending on the memory in the system.
While more sockets can be used, it is a good indicator of a worry free socket count IMHO at application launch.
nf_conntrack_max
is usually set to tcp_max_orphans
by default, if the iptables conntrack module is loaded.
Here emphasis should be on concurrent_tcp_sockets and whether we like to use this metric to limit external connections in the first place, I understand this.
It may make sense to also inject an alternative max_tcp_connections
COOLWSD configuration value.
However cropping such value to nf_conntrack_max
makes little sense, i.e. it implies the admin has to adjust the nf_conntrack_max
and (probably) tcp_max_orphans
limits anyways.
Hence we could use a config COOLWSD max_tcp_connections
, use it as-is (if given) but warn if the system getMaxConcurrentTCPConnections
is lower (-> for the system admin)?
Now if we look at the memory based Linux defaults here, i.e. 4 sockets/MB or 262k sockets for 64G etc,
it looks to me that these are good values. Whenever this issue is discussed in the web server space,
it is said to increase the same system limits to achieve a higher concurrent responsiveness while
(need to) maintain the DoS balance - if that makes sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The setting is some random other number - for a different use-case. It may often be initialized to something sensible - but it's really for a different purpose AFAICS.
So - fine; lets do this guess-timate thing - but we need to provide a setting to override it, in the case that someone really wants to configure their orphans in some way - and not crop the number of clients connections we can support.
Signed-off-by: Sven Göthel <[email protected]> Change-Id: Iad74f253bdac5636757b130b299b5deacda658db
…connections, disable if undefined or below threshold Used system value on a Linux kernel are - /proc/sys/net/ipv4/tcp_max_orphans See https://www.kernel.org/doc/html/latest/networking/ip-sysctl.html - /proc/sys/net/nf_conntrack_max See https://www.kernel.org/doc/html/latest/networking/nf_conntrack-sysctl.html Value is memory bound. On GNU/Linux approximately 4 concurrent TCP connections per MB system memory are provided, e.g. {4096M -> 16384}, {16384M -> 65536}, {65407M -> 262144}, ... Signed-off-by: Sven Göthel <[email protected]> Change-Id: Iad74f253bdac5636757b130b299b5deacda658db
d95881e
to
0175d07
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some more work to do - as well as splitting from the underlying un-necessary extra commit.
char* endptr = nullptr; | ||
errno = 0; // Flush previous error indicator. Reminder: errno is thread-local | ||
const unsigned long long num = std::strtoull(line, &endptr, 10); | ||
if (0 != errno || nullptr == endptr || endptr == line || num > std::numeric_limits<size_t>::max()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
0 != errno to errno != 0 - as previously discussed. We use !ptr - ~everywhere for null pointer checking & readability - as above - please use that idiom - and above twice.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Either way - I don't believe any of this error detection is helpful; if you read systemd you'll see they use sscanf() to parse /proc output - the format and it content is well defined and must be backwards compatible. Lets use stroll as is done in the functions above; and lets split this out into its own readDecimal function instead of having this in-line function - but lets give it a name that doesn't suck - and fits into the existing naming convention - I believe I asked for that before.
}; | ||
// - 4 tcp_max_orphans sockets per MB | ||
// - {4096M -> 16384}, {16384M -> 65536}, {65407M -> 262144}, ... | ||
const ssize_t tcp_max_orphans = readDecimal("/proc/sys/net/ipv4/tcp_max_orphans", 0); // ignored if n/a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The setting is some random other number - for a different use-case. It may often be initialized to something sensible - but it's really for a different purpose AFAICS.
So - fine; lets do this guess-timate thing - but we need to provide a setting to override it, in the case that someone really wants to configure their orphans in some way - and not crop the number of clients connections we can support.
<< res_min | ||
<< ", cut-off-min " << cutOffMinimum | ||
<< ") -> " << res_clipped); | ||
return res_clipped; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems it is very likely that this function returns zero - is that expected ?
The cutOffMinimum and the way it is injected here is really non-intuitive. Can you add a one-line comments against each line of your ? operator logic above to explain what is going on. We have two metaphores for the same thing 'cut-off' and 'clipped' - please choose something consistent for the variable naming to give the next poor reader a clue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor changes but lets get them done first.
Summary
net::Defaults.maxTCPConnections: Use system's maximum concurrent TCP connections, disable if undefined or below threshold
Used system value on a Linux kernel are
See https://www.kernel.org/doc/html/latest/networking/ip-sysctl.html
See https://www.kernel.org/doc/html/latest/networking/nf_conntrack-sysctl.html
Value is memory bound. On GNU/Linux approximately 4 concurrent TCP connections per MB system memory are provided, e.g.
Checklist
make prettier-write
and formatted the code.make check
make run
and manually verified that everything looks okay