Service IDs are assigned by the framework upon service registration. Each new id must be larger than all previously used ids (within that framework launch cycle). This is mandated by the OSGi specification. See section 5.2.5 in the Core spec (so I guess that book is wrong on this topic).
So a lower service id represents a service which was registered earlier than a service with a higher service id. So when ranking is equal, the earlier registered service is chosen.