jd-opensource / joyrpc Goto Github PK
View Code? Open in Web Editor NEWhigh-performance, high-extensibility Java rpc framework.
License: Apache License 2.0
high-performance, high-extensibility Java rpc framework.
License: Apache License 2.0
joyrpc-test模块下已移除joyrpc-test-transport,但是pom.xml未进行相应移除,编译错误。
错误信息如下:
[ERROR] Child module /Users/silence/Projects/joyrpc/joyrpc-test/joyrpc-test-transport/pom.xml of /Users/silence/Projects/joyrpc/joyrpc-test/pom.xml does not exist @ [WARNING] 'dependencies.dependency.(groupId:artifactId:type:classifier)' must be unique: com.hazelcast:hazelcast:jar -> duplicate declaration of version (?) @ line 37, column 21
PS:最近一段时间核心代码变更频繁且比较大,是有什么重大Feature么?
个人很喜欢extension的插件加载设计,鉴于目前没有找到类似的库有此功能,所以日常项目中引用joyrpc-extension-core与joyrpc-extension-springboot这些模块在其他的项目开发中使用,但是这些模块没有发布到maven**仓库,使用有些不便。
不知可否将extension下的各模块发布到maven**仓库,供人使用?
其实我看joyqueue里面也有这个包的使用,不过叫laf-extension-core,想必应该是同一个吧。统一一下用一个呢?
joyrpc是否可以在生产环境使用,HttpRegistry注册中心是做什么用的,谢谢
Hi, In joyrpc-1.4.7/joyrpc-plugin/joyrpc-transport/joyrpc-transport-resteasy,there is a dependency org.jboss.resteasy:resteasy-jaxrs:3.0.8.Final that calls the risk method.
The scope of this CVE affected version is [,3.1.0.CR1)
After further analysis, in this project, the main Api called is <org.jboss.resteasy.core.AsynchronousDispatcher: void postJob(org.jboss.resteasy.spi.HttpRequest,org.jboss.resteasy.spi.HttpResponse,org.jboss.resteasy.core.ResourceInvoker)>
Risk method repair link : GitHub
CVE Bug Invocation Path--
Path Length : 5
<org.jboss.resteasy.core.AsynchronousDispatcher: void postJob(org.jboss.resteasy.spi.HttpRequest,org.jboss.resteasy.spi.HttpResponse,org.jboss.resteasy.core.ResourceInvoker)>
at <org.jboss.resteasy.core.AsynchronousDispatcher: void invoke(org.jboss.resteasy.spi.HttpRequest,org.jboss.resteasy.spi.HttpResponse,org.jboss.resteasy.core.ResourceInvoker)> (org.jboss.resteasy.core.AsynchronousDispatcher.java:[245]) in /.m2/repository/org/jboss/resteasy/resteasy-jaxrs/3.0.8.Final/resteasy-jaxrs-3.0.8.Final.jar
at <org.jboss.resteasy.core.SynchronousDispatcher: void invokePropagateNotFound(org.jboss.resteasy.spi.HttpRequest,org.jboss.resteasy.spi.HttpResponse)> (org.jboss.resteasy.core.SynchronousDispatcher.java:[217]) in /.m2/repository/org/jboss/resteasy/resteasy-jaxrs/3.0.8.Final/resteasy-jaxrs-3.0.8.Final.jar
at <org.jboss.resteasy.plugins.server.netty.RequestDispatcher: void service(org.jboss.resteasy.spi.HttpRequest,org.jboss.resteasy.spi.HttpResponse,boolean)> (org.jboss.resteasy.plugins.server.netty.RequestDispatcher.java:[85]) in /.m2/repository/org/jboss/resteasy/resteasy-netty4/3.0.8.Final/resteasy-netty4-3.0.8.Final.jar
at <io.joyrpc.transport.resteasy.handler.RestEasyDispatcher: void channelRead0(io.netty.channel.ChannelHandlerContext,java.lang.Object)> (io.joyrpc.transport.resteasy.handler.RestEasyDispatcher.java:[76]) in /detect/unzip/joyrpc-1.4.7-RELEASE/joyrpc-plugin/joyrpc-transport/joyrpc-transport-resteasy/target/classes
Dependency tree--
[INFO] io.joyrpc:joyrpc-transport-resteasy:jar:1.4.7-RELEASE
[INFO] +- io.joyrpc:joyrpc-core:jar:1.4.7-RELEASE:compile
[INFO] | +- io.joyrpc:joyrpc-api:jar:1.4.7-RELEASE:compile
[INFO] | +- javax.validation:validation-api:jar:2.0.1.Final:compile
[INFO] | +- org.hibernate.validator:hibernate-validator:jar:6.0.18.Final:compile
[INFO] | | +- org.jboss.logging:jboss-logging:jar:3.4.1.Final:compile
[INFO] | | \- com.fasterxml:classmate:jar:1.5.1:compile
[INFO] | +- org.glassfish:javax.el:jar:3.0.1-b11:compile
[INFO] | +- org.slf4j:slf4j-api:jar:1.7.25:compile
[INFO] | \- io.joyrpc:joyrpc-extension-core:jar:1.4.7-RELEASE:compile
[INFO] +- io.joyrpc:joyrpc-transport-netty4:jar:1.4.7-RELEASE:compile
[INFO] | \- io.netty:netty-all:jar:4.1.53.Final:compile
[INFO] \- org.jboss.resteasy:resteasy-netty4:jar:3.0.8.Final:compile
[INFO] \- org.jboss.resteasy:resteasy-jaxrs:jar:3.0.8.Final:compile
[INFO] +- org.jboss.resteasy:jaxrs-api:jar:3.0.8.Final:compile
[INFO] +- org.jboss.spec.javax.annotation:jboss-annotations-api_1.1_spec:jar:1.0.1.Final:compile
[INFO] +- javax.activation:activation:jar:1.1:compile
[INFO] +- org.apache.httpcomponents:httpclient:jar:4.5.12:compile
[INFO] | +- org.apache.httpcomponents:httpcore:jar:4.4.13:compile
[INFO] | \- commons-codec:commons-codec:jar:1.13:compile
[INFO] +- commons-io:commons-io:jar:2.1:compile
[INFO] \- net.jcip:jcip-annotations:jar:1.0:compile
Suggested solutions:
Update dependency version
Thank you very much.
Now, it only support discover in service interface level, and it's hardly to maintain configuration, more and more service interface configuration become mess and error-prone. I think discover in application level is easy to use and ops, then discover service interface automatic, looks it not hard to realize.
`@SpringBootApplication
public class BootGeneric {
public static void main(String[] args) throws Exception{
System.setProperty("spring.profiles.active", "generic");
ConfigurableApplicationContext run = SpringApplication.run(BootGeneric.class, args);
// GenericService consumer = run.getBean(GenericService.class);
ConsumerConfig<GenericService> consumerConfig = new ConsumerConfig<>();
RegistryConfig registryConfig = new RegistryConfig("fix");
registryConfig.setAddress("dubbo://localhost:22000");
// RegistryConfig registryConfig = new RegistryConfig("broadcast");
// registryConfig.setAddress("localhost");
consumerConfig.setRegistry(registryConfig);
consumerConfig.setGeneric(true);
consumerConfig.setInterfaceClazz("io.joyrpc.example.service.DemoService");
consumerConfig.setAlias("2.0-Boot");
// consumerConfig.setInitSize(5);
consumerConfig.setLoadbalance("adaptive");
GenericService consumer = consumerConfig.refer().get();
System.out.println(consumer.hashCode()); // 异常发生
Map<String, Object> param = new HashMap<>();
//header
Map<String, Object> header = new HashMap<>();
Map<String, Object> headerAttrs = new HashMap<>();
headerAttrs.put("type", "generic");
headerAttrs.put("bodyType", "EchoData");
header.put("attrs", headerAttrs);
//body
Map<String, Object> body = new HashMap<>();
body.put("code", 1);
body.put("message", "this is body");
//body.put("class", "io.joyrpc.example.service.vo.EchoData");
//param
param.put("header", header);
param.put("body", body);
Object res1 = consumer.$invoke("echoRequest", null, new Object[]{param});
Object res2 = consumer.$invoke("echoRequestGeneric", null, new Object[]{param});
Object res3 = consumer.$invoke("echoDataRequest", null, new Object[]{param});
System.out.println("generic test is end, res is " + res1 + ", " + res2 + ", " + res3);
/*while (true) {
try {
System.out.println(consumer.$invoke("sayHello", null, new Object[]{"helloWold"}));
Thread.sleep(1000L);
} catch (InterruptedException e) {
break;
} catch (Exception e) {
try {
Thread.sleep(1000L);
} catch (InterruptedException ex) {
}
e.printStackTrace();
}
}*/
}
}`
堆栈信息:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2
at io.joyrpc.config.AbstractConsumerConfig$ConsumerInvokeHandler.invokeObjectMethod(AbstractConsumerConfig.java:983)
at io.joyrpc.config.AbstractConsumerConfig$ConsumerInvokeHandler.invoke(AbstractConsumerConfig.java:911)
at io.joyrpc.config.AbstractConsumerConfig$AbstractConsumerController.invoke(AbstractConsumerConfig.java:835)
at io.joyrpc.config.AbstractConsumerConfig.lambda$proxy$0(AbstractConsumerConfig.java:262)
at io.joyrpc.proxy.bytebuddy.ByteBuddyInvocationHandler.invoke(ByteBuddyInvocationHandler.java:65)
at io.joyrpc.GenericService$ByteBuddy$ZxdFPy6i.hashCode(Unknown Source)
at io.joyrpc.example.boot.BootGeneric.main(BootGeneric.java:52)
In SpringLoader class, line 113.
Method[] methods = clazz.getMethods();
It will lose bean objects that are not defined as public.
Method[] methods = clazz.getDeclaredMethods();
Will be better, I think.
业务上云是陆陆续续过程,打通网络后, 实现双注册、双发现. ,兼容 云上业务与内部业务通信问题场景, 兼容部分业务迁移场景。
1.ExtensionSpi
@Override
public ExtensionMeta<T, M> meta(final M name) {
ExtensionMeta<T, M> result = null;
if (name != null) {
//按照插件名称获取
result = names.get(name);
if (result == null) {
//没有找到,猜测名称里面是有提供商
if (name instanceof String) {
result = providers.get(name);
if (result == null) {
//供应商也没有找到,则尝试去掉供应商查找
String v = (String) name;
int pos = v.indexOf('@');
if (pos > 0) {
result = names.get(name);
}
}
}
}
}
return result;
}
好像没有去掉'@供应商',建议
result = names.get(v.substring(0,pos));
2.Timer
protected void flush(final Consumer<Task> consumer) {
List<Task> ts = new LinkedList<>();
Task task = root.next;
while (task != root) {
remove(task);
ts.add(task);
task = root.next;
}
expiration = -1L;
ts.forEach(consumer);
}
flush方法consumer执行的逻辑如下,Slot中的到期任务提交给线程池
似乎没有花费太多时间
protected void supply(final Task task) {
//添加失败任务直接执行
if (!timeWheel.add(task)) {
workerPool.submit(task);
}
}
flush方法建议
protected void flush(final Consumer<Task> consumer) {
Task task = root.next;
while (task != root) {
remove(task);
consumer.accept(task);
task = root.next;
}
expiration = -1L;
}
protected LongAdder tasks = new LongAdder();
Thanks.
首先为了方便测试,Timer.Task的代码做了两处调整,如下:
1.构造方法新增了createTime,expirationTime。分别表示任务投递时间、以及任务预期的到期时间
public Task(final String name, final long time, final Runnable runnable,
final Consumer<Task> afterRun,
final Consumer<Task> afterCancel) {
this.time = time;
this.name = name;
this.runnable = runnable;
this.afterRun = afterRun;
this.afterCancel = afterCancel;
this.slot = null;
this.next = null;
this.pre = null;
this.createTime = System.currentTimeMillis();
this.expirationTime = this.createTime + this.time;
}
2.run方法直接打印任务的信息
public void run() {
if (STATE_UPDATER.compareAndSet(this, INIT, EXPIRED)) {
//runnable.run();
long executeTime = System.currentTimeMillis();
long delayTime = executeTime - this.createTime;
StringBuilder builder = new StringBuilder();
builder.append("=============执行:" + name + "\n");
builder.append(" 任务生成时间:" + this.createTime + "\n");
builder.append(" 预期执行时间:" + expirationTime + "\n");
builder.append(" 实际执行时间:" + executeTime + "\n");
builder.append(" 实际延迟时间:" + delayTime + "\n");
System.out.println(builder);
if (afterRun != null) {
afterRun.accept(this);
}
}
}
测试数据:
public static void main(String[] args) {
Timer timer = new Timer(100L, 10, 100);
Timer.Task task;
task = new Timer.Task("50毫秒任务",50, () -> {}, o -> {}, o -> {});
timer.add(task);
task = new Timer.Task( "110毫秒任务",110, () -> {}, o -> {}, o -> {});
timer.add(task);
task = new Timer.Task( "120毫秒任务",120, () -> {}, o -> {}, o -> {});
timer.add(task);
task = new Timer.Task( "130毫秒任务",130, () -> {}, o -> {}, o -> {});
timer.add(task);
task = new Timer.Task( "230毫秒任务",230, () -> {}, o -> {}, o -> {});
timer.add(task);
task = new Timer.Task( "240毫秒任务",240, () -> {}, o -> {}, o -> {});
timer.add(task);
task = new Timer.Task( "260毫秒任务",260, () -> {}, o -> {}, o -> {});
timer.add(task);
task = new Timer.Task( "1500毫秒任务", 1500, () -> {}, o -> {}, o -> {});
timer.add(task);
task = new Timer.Task( "3000毫秒任务", 3000, () -> {}, o -> {}, o -> {});
timer.add(task);
task = new Timer.Task( "10000毫秒任务", 10000, () -> {}, o -> {}, o -> {});
timer.add(task);
task = new Timer.Task( "60000毫秒任务", 60000, () -> {}, o -> {}, o -> {});
timer.add(task);
}
测试结果:
=============执行:50毫秒任务
任务生成时间:1636949674442
预期执行时间:1636949674492
实际执行时间:1636949674555
实际延迟时间:113
=============执行:230毫秒任务
任务生成时间:1636949674445
预期执行时间:1636949674675
实际执行时间:1636949674555
实际延迟时间:110
=============执行:240毫秒任务
任务生成时间:1636949674446
预期执行时间:1636949674686
实际执行时间:1636949674555
实际延迟时间:109
=============执行:130毫秒任务
任务生成时间:1636949674445
预期执行时间:1636949674575
实际执行时间:1636949674555
实际延迟时间:110
=============执行:110毫秒任务
任务生成时间:1636949674443
预期执行时间:1636949674553
实际执行时间:1636949674555
实际延迟时间:112
=============执行:120毫秒任务
任务生成时间:1636949674444
预期执行时间:1636949674564
实际执行时间:1636949674555
实际延迟时间:111
=============执行:10000毫秒任务
任务生成时间:1636949674449
预期执行时间:1636949684449
实际执行时间:1636949674556
实际延迟时间:107
=============执行:3000毫秒任务
任务生成时间:1636949674448
预期执行时间:1636949677448
实际执行时间:1636949674555
实际延迟时间:107
=============执行:1500毫秒任务
任务生成时间:1636949674447
预期执行时间:1636949675947
实际执行时间:1636949674555
实际延迟时间:108
=============执行:260毫秒任务
任务生成时间:1636949674447
预期执行时间:1636949674707
实际执行时间:1636949674555
实际延迟时间:108
=============执行:60000毫秒任务
任务生成时间:1636949674449
预期执行时间:1636949734449
实际执行时间:1636949674556
实际延迟时间:107
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.