The author | citizen dubbo – go community source committer | alibaba cloud native public number
This article will teach you how to use Dubbogo to call a service provider provided by Dubbogo or Dubbo.
preface
This article is based on dubbogo version 1.5.4.
Recently, I started to participate in some development tests of DubboGo. Before, I used samples directly to verify functions, but this time, in order to reproduce a functional problem, I planned to build a project of Dubbo-Go and Dubbo call from scratch, and I stepped in the pit of some newcomers using Dubbogo. Document this process for your reference.
You can learn from this article:
- How to routinely configure dubbogo consumers to invoke Dubbo and Dubbogo service providers.
- Introduce the idea of solving the problem through an actual BUG.
To solve the problem
1. Prepare a Dubbo service provider
1) Basic definitions
Define the DemoService interface:
public interface DemoService {
String sayHello(String name);
String sayHello(User user);
String sayHello(User user, String name);
}
Copy the code
Define the User object:
public class User implements Serializable { private String name; private int age; . }Copy the code
2) Start the Dubbo service provider
Official example code for dubbo:
Public static void main(String[] args) throws IOException {// Service implementation DemoService DemoService = new DemoServiceImpl(); ApplicationConfig application = new ApplicationConfig(); application.setName("demoProvider"); RegistryConfig registry = new RegistryConfig(); Registry. SetAddress (127.0.0.1: "2181"); registry.setProtocol("zookeeper"); registry.setUsername(""); registry.setPassword(""); ProtocolConfig protocol = new ProtocolConfig(); protocol.setName("dubbo"); protocol.setPort(12345); protocol.setThreads(200); / / note: // The service provider exposes the service configuration. ServiceConfig<DemoService> service = new ServiceConfig<>(); // This instance is very heavy and encapsulates the connection to the registry. Please cache it yourself, otherwise it may cause memory and connection leakage. service.setRegistry(registry); // Multiple registries can use setRegistries() service-setProtocol (protocol); // setProtocols() service.setInterface(demoservice.class); service.setRef(demoService); Service. SetVersion (" 1.0.0 "); service.setGroup("tc"); service.setTimeout(60 * 1000); // Expose and register service service.export(); System.in.read(); }Copy the code
Check whether zooKeeper is successfully registered.
$ls /dubbo/com.funnycode.DemoService/providers [dubbo % 3 a % 2 f % 2 f127. 0.0.1%3 a12345%2 fcom. Funnycode. DemoService % 3 fanyhost % 3 dtrue % 26 application % 3 ddemoprovider % % 26 deprecated 3 dfalse % 26 dubbo % 3 d2. The 0.2% % 26 dynamic 3 dtrue % 26 generic % 3 dfalse % 26 group % 3 DTC % 26 interface % 3 dcom. The funnycode. DemoService % 26 method S % 3 dsayhello % 26 pid % 3 d18167%26 release % 3 d2. The 7.7% % 26 revision 3 d1. 0.0% % 26 side 3 dprovider % 26 threads % 3 d200 af must not be % 26 timestamp d16068960%3 0.0] 20691% 26 version % 3 d1.Copy the code
The above output indicates that the service provider has been started.
2. Prepare dubbogo service for consumers
1) Basic definitions
Define the User object:
type User struct {
Name string
Age int
}
func (User) JavaClassName() string {
return "com.funnycode.User"
}
Copy the code
Define the DemoProvider interface:
type DemoProvider struct {
SayHello func(ctx context.Context, name string) (string, error) `dubbo:"sayHello"`
SayHello2 func(ctx context.Context, user User) (string, error) `dubbo:"sayHello"`
SayHello3 func(ctx context.Context, user User, name string) (string, error) `dubbo:"sayHello"`
}
func (p *DemoProvider) Reference() string {
return "DemoProvider"
}
Copy the code
2) Start dubbogo consumers
func main() { config.Load() gxlog.CInfo("\n\n\nstart to test dubbo") res, err := demoProvider.SayHello(context.TODO(), "tc") if err ! = nil { panic(err) } gxlog.CInfo("response result: %v\n", res) user := User{ Name: "tc", Age: 18, } res, err = demoProvider.SayHello2(context.TODO(), user) if err ! = nil { panic(err) } gxlog.CInfo("response result: %v\n", res) res, err = demoProvider.SayHello3(context.TODO(), user, "tc") if err ! = nil { panic(err) } gxlog.CInfo("response result: %v\n", res) initSignal() }Copy the code
3. Request results analysis
1) Direct call
Identify the problem.
[2020-12-03/18:59:12 main.main: client.go: 29] Response result: Hello TC.
The second and third interfaces have User objects and cannot be called successfully. The error message is as follows:
2020-12-02T17:10:47.739+0800 INFO Getty /listener.go:87 session{session session-closed, Read Bytes: 924, Write Bytes: 199, Read Pkgs: 0, Write Pkgs: 1} got error{java exception:Fail to decode request due to: java.lang.IllegalArgumentException: Service not found:com.funnycode.DemoService, sayHello at org.apache.dubbo.rpc.protocol.dubbo.DecodeableRpcInvocation.decode(DecodeableRpcInvocation.java:134) at org.apache.dubbo.rpc.protocol.dubbo.DecodeableRpcInvocation.decode(DecodeableRpcInvocation.java:80) at org.apache.dubbo.remoting.transport.DecodeHandler.decode(DecodeHandler.java:57) at org.apache.dubbo.remoting.transport.DecodeHandler.received(DecodeHandler.java:44) at org.apache.dubbo.remoting.transport.dispatcher.ChannelEventRunnable.run(ChannelEventRunnable.java:57) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748) }, will be closed.Copy the code
Error as described in the same issue, because the error information returned to the consumer side, you can see a Java error stack information over there, so directly to visit DecodeableRpcInvocation. Decode# 134.
2) Breakpoint view
The code is as follows:
Public class DecodeableRpcInvocation extends RpcInvocation implements Codec, Decodeable { public Object decode(Channel channel, InputStream input) throws IOException { ...... if (serviceDescriptor ! = null) {/ / methods describe it according to the method name lookup MethodDescriptor MethodDescriptor = serviceDescriptor. GetMethod (getMethodName (), desc); if (methodDescriptor ! = null) { pts = methodDescriptor.getParameterClasses(); this.setReturnTypes(methodDescriptor.getReturnTypes()); If (PTS == dubbocodec.empty_class_array) {if (! RpcUtils.isGenericCall(path, getMethodName()) && ! RpcUtils.isEcho(path, getMethodName())) { throw new IllegalArgumentException("Service not found:" + path + ", " + getMethodName()); } pts = ReflectUtils.desc2classArray(desc); }... }}Copy the code
- To view
MethodDescriptor
That is, find if the method exists, and if it does, it will be setParameterClasses
. - If I don’t find anything on it,
pts == DubboCodec.EMPTY_CLASS_ARRAY
If it is a generalization call or an echo call, then the service cannot find a method error. - Desc is
Ljava/lang/Object
It is obvious that there is no method that takes an Object as an argument, so an error must be reported.
Note: Method query. The ** code is as follows:
public MethodDescriptor getMethod(String methodName, String params) {
Map<String, MethodDescriptor> methods = descToMethods.get(methodName);
if (CollectionUtils.isNotEmptyMap(methods)) {
return methods.get(params);
}
return null;
}
Copy the code
Advantages: compared to the previous version of the method added to the meta information cache, does not use reflection can improve efficiency, can understand the use of space for time.
4. Solve problems
Because the code can’t be handled directly, use comparison to see where the problem lies.
1) Start dubbo service consumers
Start in API mode, refer to the official example. This is started to see the Java version of the transport.
Public static void main(String[] args) throws InterruptedException {// Current application configuration ApplicationConfig Application = new ApplicationConfig(); application.setName("demoProvider2"); RegistryConfig registry = new RegistryConfig(); Registry. SetAddress (127.0.0.1: "2181"); registry.setProtocol("zookeeper"); registry.setUsername(""); registry.setPassword(""); / / note: ReferenceConfig is a heavy object that internally encapsulates the connection to the registry, ReferenceConfig<DemoService> reference = new ReferenceConfig<>(); // This instance is very heavy and encapsulates the connection to the registry and the connection to the provider. Please cache it yourself, otherwise it may cause memory and connection leakage. SetApplication (application); reference.setRegistry(registry); // Multiple registries can use setRegistries() reference.setInterface(demoservice.class); Reference. SetVersion (" 1.0.0 "); reference.setGroup("tc"); reference.setCheck(true); reference.setTimeout(1000 * 60); // Use xxxService DemoService DemoService = reference.get(); System.out.println(demoservice.sayHello (new User("tc", 18))); TimeUnit.MINUTES.sleep(10); }Copy the code
Desc is Lcom/funnycode/User, which is the correct object.
2) Why is it wrong to find Dubbogo
Code location: protocol/dubbo/impl/hessian. Go: 120 # marshalRequest
Code implementation:
func marshalRequest(encoder *hessian.Encoder, p DubboPackage) ([]byte, error) { service := p.Service request := EnsureRequestPayload(p.Body) encoder.Encode(DEFAULT_DUBBO_PROTOCOL_VERSION) encoder.Encode(service.Path) encoder.Encode(service.Version) encoder.Encode(service.Method) args, ok := request.Params.([]interface{}) if ! ok { logger.Infof("request args are: %+v", request.Params) return nil, perrors.Errorf("@params is not of type: []interface{}") } types, err := getArgsTypeList(args) if err ! = nil { return nil, perrors.Wrapf(err, " PackRequest(args:%+v)", args) } encoder.Encode(types) for _, v := range args { encoder.Encode(v) } ...... }Copy the code
The breakpoint shows that the types return Object, not User, so go ahead and look at the code.
protocol/dubbo/impl/hessian.go:394#getArgsTypeList
protocol/dubbo/impl/hessian.go:418#getArgType
Func getArgType(v interface{}) string {// Common type handling...... default: t := reflect.TypeOf(v) if reflect.Ptr == t.Kind() { t = reflect.TypeOf(reflect.ValueOf(v).Elem()) } switch t.Kind() { case reflect.Struct: return "java.lang.Object" } ...... }Copy the code
Java.lang.Object is returned when reflect.Struct is found, so the argument becomes Object, so the call fails because the Java code depends on this type.
3) Verification of other versions
Since the feedback is error 2.7.7, we first consider whether the function is normal in the previous version, so we switch the service provider to Dubbo 2.7.3, and find that there are still errors in the call, as follows:
2020-12-02T21:52:25.945+0800 INFO Getty /listener.go:85 session{session session-closed, Read Bytes: 4586, Write Bytes: 232, Read Pkgs: 0, Write Pkgs: 1} got error{java exception:org.apache.dubbo.rpc.RpcException: Failed to invoke remote proxy method sayHello to registry: / / 127.0.0.1:2181 / org. Apache. Dubbo. Registry. RegistryService? Application = demoProvider&dubbo = 2.0.2 & export = dubbo % 3 a % 2 f % 2 f192 168.0.113%3 a12345%2 fcom. Funnycode. 3 fanyhost DemoService % % 3 d True % 26 application % 3 ddemoprovider % 26 bind. The IP % 3 d192. 168.0.113%26 bind. The port % 3 d12345%26 deprecated % 3 dfalse % 26 dubbo % 3 d2. The 0.2% 26 d ynamic%3Dtrue%26generic%3Dfalse%26group%3Dtc%26interface%3Dcom.funnycode.DemoService%26methods%3DsayHello%26pid%3D23889% 26 the register % 3 dtrue % 26 release % 3 d2. The 7.3% % 26 revision 3 d1. 0.0% % 26 side 3 dprovider % 26 threads % 3 d200 af must not be % 26 timeout % 3 d60000%26 timestamp % 3 D1606916702204%26 version % 3 d1. 0.0 & pid = 23889 & registry = zookeeper&release = 2.7.3 & timestamp = 1606916702193, cause: Not found method "sayHello" in class com.funnycode.DemoServiceImpl. org.apache.dubbo.rpc.RpcException: Failed to invoke remote proxy method sayHello to registry: / / 127.0.0.1:2181 / org. Apache. Dubbo. Registry. RegistryService? Application = demoProvider&dubbo = 2.0.2 & export = dubbo % 3 a % 2 f % 2 f192 168.0.113%3 a12345%2 fcom. Funnycode. 3 fanyhost DemoService % % 3 d True % 26 application % 3 ddemoprovider % 26 bind. The IP % 3 d192. 168.0.113%26 bind. The port % 3 d12345%26 deprecated % 3 dfalse % 26 dubbo % 3 d2. The 0.2% 26 d ynamic%3Dtrue%26generic%3Dfalse%26group%3Dtc%26interface%3Dcom.funnycode.DemoService%26methods%3DsayHello%26pid%3D23889% 26 the register % 3 dtrue % 26 release % 3 d2. The 7.3% % 26 revision 3 d1. 0.0% % 26 side 3 dprovider % 26 threads % 3 d200 af must not be % 26 timeout % 3 d60000%26 timestamp % 3 D1606916702204%26 version % 3 d1. 0.0 & pid = 23889 & registry = zookeeper&release = 2.7.3 & timestamp = 1606916702193, cause: Not found method "sayHello" in class com.funnycode.DemoServiceImpl. at org.apache.dubbo.rpc.proxy.AbstractProxyInvoker.invoke(AbstractProxyInvoker.java:107) at org.apache.dubbo.config.invoker.DelegateProviderMetaDataInvoker.invoke(DelegateProviderMetaDataInvoker.java:56) at org.apache.dubbo.rpc.protocol.InvokerWrapper.invoke(InvokerWrapper.java:56) at org.apache.dubbo.rpc.filter.ExceptionFilter.invoke(ExceptionFilter.java:55) at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:82) at org.apache.dubbo.monitor.support.MonitorFilter.invoke(MonitorFilter.java:92) at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:82) at org.apache.dubbo.rpc.filter.TimeoutFilter.invoke(TimeoutFilter.java:48) at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:82) at org.apache.dubbo.rpc.protocol.dubbo.filter.TraceFilter.invoke(TraceFilter.java:81) at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:82) at org.apache.dubbo.rpc.filter.ContextFilter.invoke(ContextFilter.java:96) at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:82) at org.apache.dubbo.rpc.filter.GenericFilter.invoke(GenericFilter.java:148) at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:82) at org.apache.dubbo.rpc.filter.ClassLoaderFilter.invoke(ClassLoaderFilter.java:38) at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:82) at org.apache.dubbo.rpc.filter.EchoFilter.invoke(EchoFilter.java:41) at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:82) at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$CallbackRegistrationInvoker.invoke(ProtocolFilterWrapper.java:157) at org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol$1.reply(DubboProtocol.java:152) at org.apache.dubbo.remoting.exchange.support.header.HeaderExchangeHandler.handleRequest(HeaderExchangeHandler.java:102) at org.apache.dubbo.remoting.exchange.support.header.HeaderExchangeHandler.received(HeaderExchangeHandler.java:193) at org.apache.dubbo.remoting.transport.DecodeHandler.received(DecodeHandler.java:51) at org.apache.dubbo.remoting.transport.dispatcher.ChannelEventRunnable.run(ChannelEventRunnable.java:57) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748) Caused by: org.apache.dubbo.common.bytecode.NoSuchMethodException: Not found method "sayHello" in class com.funnycode.DemoServiceImpl. at org.apache.dubbo.common.bytecode.Wrapper1.invokeMethod(Wrapper1.java) at org.apache.dubbo.rpc.proxy.javassist.JavassistProxyFactory$1.doInvoke(JavassistProxyFactory.java:47) at org.apache.dubbo.rpc.proxy.AbstractProxyInvoker.invoke(AbstractProxyInvoker.java:84) ... 27 more }, will be closed.Copy the code
The method is not found in the proxy enhancement class. The reflection method is not found in the proxy enhancement class, so it is a parameter problem.
4) Fix the problem
The fix is relatively simple, just get the JavaClassName defined by the struct.
case reflect.Struct:
v, ok := v.(hessian.POJO)
if ok {
return v.JavaClassName()
}
return "java.lang.Object"
Copy the code
5) Verify the results
Execute consumer again, running (provider 2.7.7 and 2.7.3) normal, output is as follows:
[2020-12-03/20:04:06 main.main: client.go: 29] response result: Hello tc
...
[2020-12-03/20:04:09 main.main: client.go: 41] response result: Hello tc You are 18
...
[2020-12-03/20:04:09 main.main: client.go: 48] response result: Hello tc You are 18
Copy the code
Details about
1. How to configure Dubbogo consumers
Have you noticed that the consumer interface of my Dubbogo is called DemoProvider and the provider is called DemoService? How does this work?
In this configuration file, interface, version, group, etc., are specified in detail. You can also use methods to configure method timeout and other information.
References: "DemoProvider": # Use commas to separate multiple registries; Do not specify a default to all registry registry: "zk1" protocol: "dubbo" interface: "com. Funnycode. DemoService" cluster: "failover" version: "1.0.0" group: "tc" methods: - name: "SayHello" retries: 3......Copy the code
2. How to configure group and version globally
The configuration file is as follows:
# application config application: organization: "dubbogoproxy.com" name: "Demo Micro Service" module: Dubbogoproxy TC Client "version: "1.0.0" group:" TC "owner: "ZX" environment: "dev" References: "DemoProvider": You can specify multiple registries, separated by commas; Do not specify a default to all registry registry: "zk1" protocol: "dubbo" interface: "com. Funnycode. DemoService" cluster: "failover" # version: "1.0.0" # group: "tc" methods: -name: "SayHello" retries: 3Copy the code
However, I found that the version and group configured in application will not be assigned to the interface when it is started, and the service provider will not find it when it is started, as follows:
The 2020-12-03 T20:15:42. 208 + 0800 DEBUG zookeeper/registry. Go: 237 Create a zookeeper Node: dubbo/com. Funnycode. DemoService/consumers/consumer % 3 a % 2 f % 2 f30 11.176.107%2 fdemoprovider % 3 fapp. Version % 3 d1. 0.0% ap 26 plication%3DDemo+Micro+Service%26async%3Dfalse%26bean.name%3DDemoProvider%26cluster%3Dfailover%26environment%3Ddev%26gen Eric % 3 dfalse % 26 group % 3 d % 26 interface % 3 dcom. Funnycode. DemoService % 26 IP % 3 d30. 11.176.107%26 loadbalance % 3 d % 26 the methods. The SayHello .loadbalance%3D%26methods.SayHello.retries%3D3%26methods.SayHello.sticky%3Dfalse%26module%3Ddubbogoproxy+tc+client%26nam e%3DDemo+Micro+Service%26organization%3Ddubbogoproxy.com%26owner%3DZX%26pid%3D38692%26protocol%3Ddubbo%26provided-by%3D% 26. The reference filter % 3 dcshutdown % 26 registry. The role % 3 d0%26 release % 3 ddubbo golang - 1.3.0%26 retries % 3 d % 26 side % 3 dconsumer % 26 stick y%3Dfalse%26timestamp%3D1606997742%26version%3DCopy the code
Both version and Group are empty. You must open the version and group annotations under DemoProvider.
3. How to specify the method name
1) Go calls Java
Dubbogo calls dubbo, because go is a lowercase method name and Java is a lowercase method name.
2020-12-02T17:10:47.739+0800 INFO Getty /listener.go:87 session{session session-closed, Read Bytes: 924, Write Bytes: 199, Read Pkgs: 0, Write Pkgs: 1} got error{java exception:Fail to decode request due to: java.lang.IllegalArgumentException: Service not found:com.funnycode.DemoService, SayHello java.lang.IllegalArgumentException: Service not found:com.funnycode.DemoService, SayHello at org.apache.dubbo.rpc.protocol.dubbo.DecodeableRpcInvocation.decode(DecodeableRpcInvocation.java:134) at org.apache.dubbo.rpc.protocol.dubbo.DecodeableRpcInvocation.decode(DecodeableRpcInvocation.java:80) at org.apache.dubbo.remoting.transport.DecodeHandler.decode(DecodeHandler.java:57) at org.apache.dubbo.remoting.transport.DecodeHandler.received(DecodeHandler.java:44) at org.apache.dubbo.remoting.transport.dispatcher.ChannelEventRunnable.run(ChannelEventRunnable.java:57) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748) }, will be closed.Copy the code
Careful readers may have noticed that my interface declaration on the consumer side has a dubbo:”sayHello”, indicating that the method name is sayHello, so that the service provider can get the sayHello method name.
And the three methods I declared all specify that their methods are called dubbo:”sayHello”, because Java can override methods with the same name, and GO cannot duplicate method names.
2) Go call go
Just post the code that runs.
My provider interface:
type DemoProvider struct{}
func (p *DemoProvider) SayHello(ctx context.Context, name string) (string, error) {
return "Hello " + name, nil
}
func (p *DemoProvider) SayHello4(ctx context.Context, user *User) (string, error) {
return "Hello " + user.Name + " You are " + strconv.Itoa(user.Age), nil
}
func (p *DemoProvider) SayHello5(ctx context.Context, user *User, name string) (string, error) {
return "Hello " + name + " You are " + strconv.Itoa(user.Age), nil
}
func (p *DemoProvider) Reference() string {
return "DemoProvider"
}
func (p *DemoProvider) MethodMapper() map[string]string {
return map[string]string{
"SayHello": "sayHello",
}
}
Copy the code
My consumer Interface:
Struct {// Call Java and go SayHello func(CTX context. context, name string) (string, Java SayHello2 func(CTX context. context, user * user) (string, error) `dubbo:"sayHello"` SayHello3 func(ctx context.Context, user *User, name string) (string, Error) 'dubbo:"sayHello"' // only call go SayHello4 func(CTX context. context, user * user) (string, error) SayHello5 func(ctx context.Context, user *User, name string) (string, error) }Copy the code
Start service consumers:
func main() { config.Load() gxlog.CInfo("\n\n\nstart to test dubbo") res, err := demoProvider.SayHello(context.TODO(), "tc") if err ! = nil { panic(err) } gxlog.CInfo("response result: %v\n", res) user := &User{ Name: "tc", Age: 18, } res, err = demoProvider.SayHello4(context.TODO(), user) if err ! = nil { panic(err) } gxlog.CInfo("response result: %v\n", res) res, err = demoProvider.SayHello5(context.TODO(), user, "tc") if err ! = nil { panic(err) } gxlog.CInfo("response result: %v\n", res) initSignal() }Copy the code
Note the MethodMapper method, where you sometimes need to configure the mapping of method names, otherwise you’ll still fail to find the method.
For example, sayHello becomes sayHello in go because dubbo:”sayHello” is configured, so the service provider is configured with sayHello as well. So go and Java expose all lowercase sayHello.
4. Why hessian2
As any veteran driver knows, the default value of the SPI mechanism in Dubbo is hessian2
@SPI("hessian2")
public interface Serialization {
}
Copy the code
And in Dubo-Go:
func NewDubboCodec(reader *bufio.Reader) *ProtocolCodec {
s, _ := GetSerializerById(constant.S_Hessian2)
return &ProtocolCodec{
reader: reader,
pkgType: 0,
bodyLen: 0,
headerRead: false,
serializer: s.(Serializer),
}
}
Copy the code
5. Hessian serialization source code
Able to breakpoints view, both sides are basically the same, I also am than through out, RpcInvocation. GetParameterTypesDesc () is the method of parameter.
- The go code
protocol/dubbo/impl/hessian.go:120#marshalRequest
- Java code
org.apache.dubbo.rpc.protocol.dubbo.DubboCodec#encodeRequestData(org.apache.dubbo.remoting.Channel, org.apache.dubbo.common.serialize.ObjectOutput, java.lang.Object, java.lang.String)
6. The dubbogo service provider’s method object needs to be a pointer object
The previous examples are copy, this time is pure hand, found this problem. Func (p *DemoProvider) SayHello4(CTX context.context, user user) (string, error) func (p *DemoProvider) SayHello4(CTX context.context, user user) (string, error)
2020-12-03T12:42:32.834+0800 ERROR Getty /listener.go:280 OnMessage panic: reflect: Call using *main.User as type main.User github.com/apache/dubbo-go/remoting/getty.(*RpcServerHandler).OnMessage.func1Copy the code
The User in the parameter should be changed to *User.
7. Method objects of dubbogo service consumers can be non-pointer objects
SayHello4 func(ctx context.Context, user *User) (string, error)
// or
SayHello4 func(ctx context.Context, user User) (string, error)
Copy the code
Because when the argument is serialized it does something to the pointer:
t := reflect.TypeOf(v)
if reflect.Ptr == t.Kind() {
t = reflect.TypeOf(reflect.ValueOf(v).Elem())
}
Copy the code
The complete code
8. Description of the configuration file
Dubbogo has three main configuration files:
- Server. yaml Configuration file of the service provider
- Client. Yaml Configuration file of the service consumer
- Log. yaml log file
If you configure nothing, this will appear:
2021/01/11 15:31:41 [InitLog] warn: log configure file name is nil
2021/01/11 15:31:41 [consumerInit] application configure(consumer) file name is nil
2021/01/11 15:31:41 [providerInit] application configure(provider) file name is nil
Copy the code
It’s not going to work. If you are a service provider, you must configure the server.yaml file. If you are a service consumer, you must configure the client.yaml file.
If the service provider starts normally, the following output is displayed:
The 2021-01-11 T15:36:55. 003 + 0800 INFO protocol/protocol. Go: 205 The cached exporter keys is dubbo: / / : 20000 / DemoProvider? Accesslog = & app. Version = 1.0.0 & application = Demo + Micro + Service&auth = & bean. The name = DemoProvider&cluster = failover&environment = DE v&execute.limit=&execute.limit.rejected.handler=&group=tc&interface=com.funnycode.DemoService&loadbalance=random&methods .SayHello.loadbalance=random&methods.SayHello.retries=3&methods.SayHello.tps.limit.interval=&methods.SayHello.tps.limit. rate=&methods.SayHello.tps.limit.strategy=&methods.SayHello.weight=0&methods.SayHello4.loadbalance=random&methods.SayHel lo4.retries=3&methods.SayHello4.tps.limit.interval=&methods.SayHello4.tps.limit.rate=&methods.SayHello4.tps.limit.strate gy=&methods.SayHello4.weight=0&methods.SayHello5.loadbalance=random&methods.SayHello5.retries=3&methods.SayHello5.tps.li mit.interval=&methods.SayHello5.tps.limit.rate=&methods.SayHello5.tps.limit.strategy=&methods.SayHello5.weight=0&module= dubbogoproxy+tc+client&name=Demo+Micro+Service&organization=dubbogoproxy.com&owner=ZX¶m.sign=®istry.role=3&releas E = dubbo - golang - 1.3.0 & retries = & serialization = & service. The filter = echo % 2 ctoken % 2 caccesslog % 2 CTPS % 2 cgeneric_service % 2 cexecute % 2 Cpshutdown&side=provider&ssl-enabled=false×tamp=1610350614&tps.limit.interval=&tps.limit.rate=&tps.limit.rejected.h Andler = & TPS. Limit. The strategy = & TPS. The limiter = & version = 1.0.0 & warmup = 100! The 2021-01-11 T15:36:55. 003 + 0800 INFO dubbo/dubbo_protocol go: 86 Export service: dubbo: / / : 20000 / DemoProvider? Accesslog = & app. Version = 1.0.0 & application = Demo + Micro + Service&auth = & bean. The name = DemoProvider&cluster = failover&environment = DE v&execute.limit=&execute.limit.rejected.handler=&group=tc&interface=com.funnycode.DemoService&loadbalance=random&methods .SayHello.loadbalance=random&methods.SayHello.retries=3&methods.SayHello.tps.limit.interval=&methods.SayHello.tps.limit. rate=&methods.SayHello.tps.limit.strategy=&methods.SayHello.weight=0&methods.SayHello4.loadbalance=random&methods.SayHel lo4.retries=3&methods.SayHello4.tps.limit.interval=&methods.SayHello4.tps.limit.rate=&methods.SayHello4.tps.limit.strate gy=&methods.SayHello4.weight=0&methods.SayHello5.loadbalance=random&methods.SayHello5.retries=3&methods.SayHello5.tps.li mit.interval=&methods.SayHello5.tps.limit.rate=&methods.SayHello5.tps.limit.strategy=&methods.SayHello5.weight=0&module= dubbogoproxy+tc+client&name=Demo+Micro+Service&organization=dubbogoproxy.com&owner=ZX¶m.sign=®istry.role=3&releas E = dubbo - golang - 1.3.0 & retries = & serialization = & service. The filter = echo % 2 ctoken % 2 caccesslog % 2 CTPS % 2 cgeneric_service % 2 cexecute % 2 Cpshutdown&side=provider&ssl-enabled=false×tamp=1610350614&tps.limit.interval=&tps.limit.rate=&tps.limit.rejected.h Andler = & TPS. Limit. The strategy = & TPS. The limiter = & version = 1.0.0 & warmup = 100Copy the code
9. Duplicate code
-
Github.com/cityiron/ja…
-
Github.com/cityiron/go…
reference
-
Dubbo.apache.org/zh/docs/v2….
-
Github.com/apache/dubb…
Space is limited, so here is the introduction. Welcome to participate in the construction of dubbogo3.0. Thank you for reading. If you have any questions, please feel free to join our communication group at 31363295.
Author’s brief introduction
GithubID CityIron, Dubbo-Go Committer, mainly involved in Dubbo-Go 1.5 iteration, Dubbo-Go 3.0 service routing and cloud native, and dubbo-Go-Proxy project leader. Good at using Java/Go language, focus on cloud native and micro services and other technical direction.