Skip to content
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

[dubbo 4458] doRefer in RestProtocol may cause OOM #4629

Closed
wants to merge 11 commits into from

Conversation

finalcola
Copy link
Contributor

@finalcola finalcola commented Jul 22, 2019

What is the purpose of the change

#4458 (comment)

  1. clear resouces when invoker(AbstructProxyInvoker) is not in use:
protected <T> Invoker<T> protocolBindingRefer(final Class<T> type, final URL url) throws RpcException {
        final Invoker<T> target = proxyFactory.getInvoker(doRefer(type, url), type, url);
        Invoker<T> invoker = new AbstractInvoker<T>(type, url) {
            @Override
            protected Result doInvoke(Invocation invocation) throws Throwable {
                // do invoke...
            }

            // invokers need clear unused invoker
            @Override
            public void destroy() {
                super.destroy();
                target.destroy();
                invokers.remove(this);
            }
        };
        invokers.add(invoker);
        return invoker;
    }
  1. clear RestProtocol.cliens by using map(key is url, value is client)

Brief changelog

XXXXX

Verifying this change

XXXXX

Follow this checklist to help us incorporate your contribution quickly and easily:

  • Make sure there is a GITHUB_issue field for the change (usually before you start working on it). Trivial changes like typos do not require a GITHUB issue. Your pull request should address just this issue, without pulling in other changes - one PR resolves one issue.
  • Format the pull request title like [Dubbo-XXX] Fix UnknownException when host config not exist #XXX. Each commit in the pull request should have a meaningful subject line and body.
  • Write a pull request description that is detailed enough to understand what the pull request does, how, and why.
  • Write necessary unit-test to verify your logic correction, more mock a little better when cross module dependency exist. If the new feature or significant change is committed, please remember to add sample in dubbo samples project.
  • Run mvn clean install -DskipTests=false & mvn clean test-compile failsafe:integration-test to make sure unit-test and integration-test pass.
  • If this contribution is large, please follow the Software Donation Guide.

@finalcola finalcola closed this Jul 23, 2019
@finalcola finalcola reopened this Jul 23, 2019
@codecov-io
Copy link

codecov-io commented Jul 23, 2019

Codecov Report

Merging #4629 into master will increase coverage by 0.5%.
The diff coverage is 80.95%.

Impacted file tree graph

@@             Coverage Diff             @@
##             master    #4629     +/-   ##
===========================================
+ Coverage     63.48%   63.99%   +0.5%     
- Complexity      451      452      +1     
===========================================
  Files           789      769     -20     
  Lines         34721    33186   -1535     
  Branches       5422     5231    -191     
===========================================
- Hits          22044    21238    -806     
+ Misses        10151     9525    -626     
+ Partials       2526     2423    -103
Impacted Files Coverage Δ Complexity Δ
...g/apache/dubbo/rpc/protocol/rest/RestProtocol.java 70.07% <80.95%> (+1.85%) 0 <0> (ø) ⬇️
.../remoting/transport/netty4/NettyServerHandler.java 61.9% <0%> (-9.53%) 0% <0%> (ø)
...beans/factory/annotation/ReferenceBeanBuilder.java 68% <0%> (-7%) 0% <0%> (ø)
...ng/transport/dispatcher/all/AllChannelHandler.java 51.42% <0%> (-5.72%) 0% <0%> (ø)
.../org/apache/dubbo/remoting/ExecutionException.java 15.78% <0%> (-5.27%) 0% <0%> (ø)
.../apache/dubbo/remoting/transport/AbstractPeer.java 58.69% <0%> (-4.35%) 0% <0%> (ø)
...g/p2p/exchange/support/MulticastExchangeGroup.java 72.34% <0%> (-4.26%) 0% <0%> (ø)
...mmon/serialize/kryo/utils/AbstractKryoFactory.java 75% <0%> (-3.58%) 0% <0%> (ø)
...ava/org/apache/dubbo/config/ApplicationConfig.java 88.33% <0%> (-2.9%) 0% <0%> (ø)
...exchange/support/header/HeaderExchangeHandler.java 64.75% <0%> (-2.46%) 0% <0%> (ø)
... and 52 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 443b6ff...821a9d5. Read the comment docs.

@beiwei30
Copy link
Member

@finalcola I am not persuaded that the current solution is better than the original. The reason is, I believe 'connection manager' plus 'connection monitor' will reuse and recycle the client. The potential OOM issue may caused by 'connection manager' is not used when the client is created, which has in fact been fixed by you with another pull request: #4614

Copy link
Member

@beiwei30 beiwei30 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure this pull request is necessary.

@finalcola
Copy link
Contributor Author

#4614 will clear HTTPConnection, but RestProtocol will keep too much client(ResteasyClient) reference which makes these ResteasyClient instance can't be GC.

@finalcola
Copy link
Contributor Author

@beiwei30

@beiwei30
Copy link
Member

I see. In your solution, when will ResteasyClient be recycled?

@beiwei30
Copy link
Member

#4614 will clear HTTPConnection, but RestProtocol will keep too much client(ResteasyClient) reference which makes these ResteasyClient instance can't be GC.

a second thought: If I don't misunderstand, there's no way to recycle the clients, even if they are now saved in a map. This may lead to a potential problem, which is, the underlaying connection can be closed by connection manager (see connection monitor). If this happens, this will lead to invocation failure since the resteasy client maintained in the map doesn't have lifcecycle management.

Should we simply create Resteasy client every time and then drop it? I think it is not expensive since the connection will be reused, what do you think?

Or should we maintain the client in weak hash map instead?

@finalcola
Copy link
Contributor Author

The previous implementation was to use a List to collect clients, but add client only, never remove. Now clients are saved in map which means they are in use, and old client will be remove and close. When doRefer happens, will create a new client for this url. @beiwei30

@beiwei30
Copy link
Member

beiwei30 commented Jul 29, 2019

The previous implementation was to use a List to collect clients, but add client only, never remove. Now clients are saved in map which means they are in use, and old client will be remove and close. When doRefer happens, will create a new client for this url. @beiwei30

could you pls. point out when the client will be removed from the map? @finalcola

@finalcola
Copy link
Contributor Author

it will not remove. My original idea was that each existing url would generate only one client(previous implementation using Sync List will add client everytime), because It is not clear whether the client corresponding to the url is still in use.

maybe sync WeakHashMap can solve it, but it dose not pass the travis-ci in JDK 11.
https://travis-ci.org/apache/dubbo/builds/563891937

@beiwei30

@finalcola finalcola closed this Jul 30, 2019
@finalcola finalcola reopened this Jul 30, 2019
@finalcola
Copy link
Contributor Author

now, i use WeakRefence to hold client

@finalcola
Copy link
Contributor Author

@beiwei30 could you please have a look, if there are any problems

@finalcola finalcola closed this Aug 4, 2019
@finalcola finalcola reopened this Aug 4, 2019
@CLAassistant
Copy link

CLAassistant commented Sep 6, 2019

CLA assistant check
All committers have signed the CLA.


public void addConnectionManager(String key, PoolingHttpClientConnectionManager connectionManager) {
connectionManagers.put(key, connectionManager);
// connectionManagers.add(connectionManager);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove unuse comment

@AlbumenJ
Copy link
Member

@finalcola Hi, thanks for your contribution.

Please merge the latest master branch to resolve confilcts.

@AlbumenJ AlbumenJ added the status/waiting-for-feedback Need reporters to triage label Apr 11, 2021
@AlbumenJ
Copy link
Member

Close for long time no response.

Please feel free to reopen if you have any question.

If you think these changes still useful in the latest master branch, please submit a new pull request.

@AlbumenJ AlbumenJ closed this May 22, 2021
@codecov-commenter
Copy link

Codecov Report

Attention: Patch coverage is 80.95238% with 4 lines in your changes missing coverage. Please review.

Project coverage is 63.99%. Comparing base (443b6ff) to head (821a9d5).

Files Patch % Lines
...g/apache/dubbo/rpc/protocol/rest/RestProtocol.java 80.95% 2 Missing and 2 partials ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##             master    #4629      +/-   ##
============================================
+ Coverage     63.48%   63.99%   +0.50%     
- Complexity      451      452       +1     
============================================
  Files           789      769      -20     
  Lines         34721    33186    -1535     
  Branches       5422     5231     -191     
============================================
- Hits          22044    21238     -806     
+ Misses        10151     9525     -626     
+ Partials       2526     2423     -103     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status/waiting-for-feedback Need reporters to triage
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants