Closed seal90 closed 2 months ago
In order to help you, we need to understand your intentions/purpose better.
As shown in the figure, 'biz-service' and 'servicefilter' are two applications on the same machine. biz-service is a business applicatoin. It provides external services through grpc & protobuf, and calls other services, db, cache, etc. through this protocol (convert the interface provided by sdk to protobuf), so that all external calls made by biz-service are converted For service calls, in order to simplify biz-service, the service discovery capability is implemented by servicefilter. Therefore, biz-service needs to tell servicefilter the service name to be called. Servicefilter obtains the service instance from the registration center according to the service name and then completes the call.
The servicefilter uses ‘x-servicefilter-target-service-name’ as the key for the service name. This key and service name need to be placed in the requested Metadata. In addition to the above three adding methods, are there any more friendly adding methods?
Why don't you use the address for the service discovery similar to the DiscoveryClientNameResolver?
I want the business application to focus more on the business itself, and move the non-business code to an external program (servicefilter) as much as possible for processing, so the business application needs to tell the servicefilter the name of the application I want to call, and the servicefilter can realize discovery and transfer. In this way, business applications become very simple, and the servicefilter capabilities are universal and can be managed using simple configuration files. The overall development, operation and maintenance of the system will be much simpler. Use ‘DiscoveryClientNameResolver‘ to increase the transmission of metadata information? If so, please explain how to use it.
so the business application needs to tell the servicefilter the name of the application I want to call
So basically it's effectively a service registry
In this way, business applications become very simple, and the servicefilter capabilities are universal and can be managed using simple configuration files.
So is setting the configuration:
grpc:
client:
counter-service:
address: "service-filter:counter-service"
Dependending on your NameResolverProvider
implementation you can also omit the actual address in the config and it will use the name of the client (annotation) itself.
Use ‘DiscoveryClientNameResolver‘ to increase the transmission of metadata information? If so, please explain how to use it.
It does not add additional metadata to the request it just resolves the address the service tries to use. Similar to DNS.
So instead of doing ask dns where the service-filter is and then call service-filter to forward the call to whatever service using the call metadata
, you ask the service-filter where the whatever service is
Which service registry do you use? Eureka, Consul, Nacos, ...?
I want to use servicefilter application proxy for all network requests of business application. Take a request that requires a business application to call the database as an example. 1 The request first reaches servicefilter and is processed by servicefiter. 2 Forward to business application s1 3 s1 needs to call the db service db-001. At this time, s1 does not call db-001 directly, but calls it through the protobuf interface provided by servicefilter. 4 s1 tells servicefilter to call db-001 5 servicefilter goes to the registration center to query the instance of db-001, and then initiates a call According to this process, servicefilter needs to know the service name db-001
grpc:
server:
port: 9898
client:
GLOBAL: # Specify that all services are called to this address, which is servicefilter
address: 'static://[::1]:50052' # servicefilter local listen
enableKeepAlive: true
keepAliveWithoutCalls: true
negotiationType: plaintext
@GrpcClient(value = "redis-servicefilter-proxy", interceptors = ServicefilterMetadataClientInterceptor.class)
private RedisOperateServiceGrpc.RedisOperateServiceBlockingStub redisOperateServiceBlockingStub;
For me this looks like a service registry/discovery client setup and I think an implementation using a name resolver would be straight forward.
For me, calling the "service-filter" as a proxy in every step sounds like a waste of performance, but you might have some requirements/idea/concept that I dont know of/understand.
The alternative using headers should work as well. You should enshure that external calls to your service filter ignore the header to avoid leaking access to your DB. If it is an internal only service it doesnt matter.
The following class might help you with it/should require less code.
https://grpc.github.io/grpc-java/javadoc/io/grpc/stub/MetadataUtils.html
Does this answer your question?
Yes, thank you.
The context
I want to make business applications more focused on business. I design a program to proxy all IO of business applications. It looks like this:![servicefilter-imagine](https://github.com/grpc-ecosystem/grpc-spring/assets/40825053/1b8a7089-877a-4026-ac8c-a6c418eeb585)
This is a bit similar to server-side discovery, so I need to tell the servicefilter the target service name. I found three ways to add it, and the last one I think is the best way. Are there any other better ways?
The code like this:
@interface Metadata { String key(); String value(); }
// GrpcClientBeanPostProcessor protected List interceptorsFromAnnotation(final GrpcClient annotation) throws BeansException {
final List list = Lists.newArrayList();
// start
GrpcClient.Metadata[] metadatas = annotation.metadatas();
if(metadatas.length > 0) {
}
Program code example here: https://github.com/servicefilter/example/blob/main/README.md
The application's environment
Which versions do you use?